blob: 85ac0dd501dea5fff98801ba47edabbf972492a5 [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,
Tero Kristo2e1a7b02014-10-03 16:57:14 +030036 .set_parent = &omap3_noncore_dpll_set_parent,
37 .set_rate_and_parent = &omap3_noncore_dpll_set_rate_and_parent,
38 .determine_rate = &omap4_dpll_regm4xen_determine_rate,
Tero Kristof38b0dd2013-06-12 16:04:34 +030039 .get_parent = &omap2_init_dpll_parent,
40};
Tero Kristoaa76fcf2014-02-21 17:36:21 +020041#else
42static const struct clk_ops dpll_m4xen_ck_ops = {};
Tero Kristof38b0dd2013-06-12 16:04:34 +030043#endif
44
Tero Kristoaa76fcf2014-02-21 17:36:21 +020045#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4) || \
46 defined(CONFIG_SOC_OMAP5) || defined(CONFIG_SOC_DRA7XX) || \
47 defined(CONFIG_SOC_AM33XX) || defined(CONFIG_SOC_AM43XX)
Tero Kristof38b0dd2013-06-12 16:04:34 +030048static const struct clk_ops dpll_core_ck_ops = {
49 .recalc_rate = &omap3_dpll_recalc,
50 .get_parent = &omap2_init_dpll_parent,
51};
52
Tero Kristof38b0dd2013-06-12 16:04:34 +030053static 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,
Tero Kristo2e1a7b02014-10-03 16:57:14 +030059 .set_parent = &omap3_noncore_dpll_set_parent,
60 .set_rate_and_parent = &omap3_noncore_dpll_set_rate_and_parent,
61 .determine_rate = &omap3_noncore_dpll_determine_rate,
Tero Kristof38b0dd2013-06-12 16:04:34 +030062 .get_parent = &omap2_init_dpll_parent,
63};
64
65static const struct clk_ops dpll_no_gate_ck_ops = {
66 .recalc_rate = &omap3_dpll_recalc,
67 .get_parent = &omap2_init_dpll_parent,
68 .round_rate = &omap2_dpll_round_rate,
69 .set_rate = &omap3_noncore_dpll_set_rate,
Tero Kristo2e1a7b02014-10-03 16:57:14 +030070 .set_parent = &omap3_noncore_dpll_set_parent,
71 .set_rate_and_parent = &omap3_noncore_dpll_set_rate_and_parent,
72 .determine_rate = &omap3_noncore_dpll_determine_rate,
Tero Kristof38b0dd2013-06-12 16:04:34 +030073};
Tero Kristoaa76fcf2014-02-21 17:36:21 +020074#else
75static const struct clk_ops dpll_core_ck_ops = {};
76static const struct clk_ops dpll_ck_ops = {};
77static const struct clk_ops dpll_no_gate_ck_ops = {};
78const struct clk_hw_omap_ops clkhwops_omap3_dpll = {};
79#endif
80
81#ifdef CONFIG_ARCH_OMAP2
82static const struct clk_ops omap2_dpll_core_ck_ops = {
83 .get_parent = &omap2_init_dpll_parent,
84 .recalc_rate = &omap2_dpllcore_recalc,
85 .round_rate = &omap2_dpll_round_rate,
86 .set_rate = &omap2_reprogram_dpllcore,
87};
88#else
89static const struct clk_ops omap2_dpll_core_ck_ops = {};
90#endif
91
92#ifdef CONFIG_ARCH_OMAP3
93static const struct clk_ops omap3_dpll_core_ck_ops = {
94 .get_parent = &omap2_init_dpll_parent,
95 .recalc_rate = &omap3_dpll_recalc,
96 .round_rate = &omap2_dpll_round_rate,
97};
98#else
99static const struct clk_ops omap3_dpll_core_ck_ops = {};
100#endif
Tero Kristof38b0dd2013-06-12 16:04:34 +0300101
102#ifdef CONFIG_ARCH_OMAP3
103static const struct clk_ops omap3_dpll_ck_ops = {
104 .enable = &omap3_noncore_dpll_enable,
105 .disable = &omap3_noncore_dpll_disable,
106 .get_parent = &omap2_init_dpll_parent,
107 .recalc_rate = &omap3_dpll_recalc,
108 .set_rate = &omap3_noncore_dpll_set_rate,
Tero Kristo2e1a7b02014-10-03 16:57:14 +0300109 .set_parent = &omap3_noncore_dpll_set_parent,
110 .set_rate_and_parent = &omap3_noncore_dpll_set_rate_and_parent,
111 .determine_rate = &omap3_noncore_dpll_determine_rate,
Tero Kristof38b0dd2013-06-12 16:04:34 +0300112 .round_rate = &omap2_dpll_round_rate,
113};
114
115static const struct clk_ops omap3_dpll_per_ck_ops = {
116 .enable = &omap3_noncore_dpll_enable,
117 .disable = &omap3_noncore_dpll_disable,
118 .get_parent = &omap2_init_dpll_parent,
119 .recalc_rate = &omap3_dpll_recalc,
120 .set_rate = &omap3_dpll4_set_rate,
Tero Kristo2e1a7b02014-10-03 16:57:14 +0300121 .set_parent = &omap3_noncore_dpll_set_parent,
122 .set_rate_and_parent = &omap3_dpll4_set_rate_and_parent,
123 .determine_rate = &omap3_noncore_dpll_determine_rate,
Tero Kristof38b0dd2013-06-12 16:04:34 +0300124 .round_rate = &omap2_dpll_round_rate,
125};
126#endif
127
128static const struct clk_ops dpll_x2_ck_ops = {
129 .recalc_rate = &omap3_clkoutx2_recalc,
130};
131
132/**
133 * ti_clk_register_dpll - low level registration of a DPLL clock
134 * @hw: hardware clock definition for the clock
135 * @node: device node for the clock
136 *
137 * Finalizes DPLL registration process. In case a failure (clk-ref or
138 * clk-bypass is missing), the clock is added to retry list and
139 * the initialization is retried on later stage.
140 */
141static void __init ti_clk_register_dpll(struct clk_hw *hw,
142 struct device_node *node)
143{
144 struct clk_hw_omap *clk_hw = to_clk_hw_omap(hw);
145 struct dpll_data *dd = clk_hw->dpll_data;
146 struct clk *clk;
147
148 dd->clk_ref = of_clk_get(node, 0);
149 dd->clk_bypass = of_clk_get(node, 1);
150
151 if (IS_ERR(dd->clk_ref) || IS_ERR(dd->clk_bypass)) {
152 pr_debug("clk-ref or clk-bypass missing for %s, retry later\n",
153 node->name);
154 if (!ti_clk_retry_init(node, hw, ti_clk_register_dpll))
155 return;
156
157 goto cleanup;
158 }
159
160 /* register the clock */
161 clk = clk_register(NULL, &clk_hw->hw);
162
163 if (!IS_ERR(clk)) {
164 omap2_init_clk_hw_omap_clocks(clk);
165 of_clk_add_provider(node, of_clk_src_simple_get, clk);
166 kfree(clk_hw->hw.init->parent_names);
167 kfree(clk_hw->hw.init);
168 return;
169 }
170
171cleanup:
172 kfree(clk_hw->dpll_data);
173 kfree(clk_hw->hw.init->parent_names);
174 kfree(clk_hw->hw.init);
175 kfree(clk_hw);
176}
177
178#if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \
Roger Quadros4332ec12014-06-17 17:03:24 +0300179 defined(CONFIG_SOC_DRA7XX) || defined(CONFIG_SOC_AM33XX) || \
180 defined(CONFIG_SOC_AM43XX)
Tero Kristof38b0dd2013-06-12 16:04:34 +0300181/**
182 * ti_clk_register_dpll_x2 - Registers a DPLLx2 clock
183 * @node: device node for this clock
184 * @ops: clk_ops for this clock
185 * @hw_ops: clk_hw_ops for this clock
186 *
187 * Initializes a DPLL x 2 clock from device tree data.
188 */
189static void ti_clk_register_dpll_x2(struct device_node *node,
190 const struct clk_ops *ops,
191 const struct clk_hw_omap_ops *hw_ops)
192{
193 struct clk *clk;
194 struct clk_init_data init = { NULL };
195 struct clk_hw_omap *clk_hw;
196 const char *name = node->name;
197 const char *parent_name;
198
199 parent_name = of_clk_get_parent_name(node, 0);
200 if (!parent_name) {
201 pr_err("%s must have parent\n", node->name);
202 return;
203 }
204
205 clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL);
206 if (!clk_hw)
207 return;
208
209 clk_hw->ops = hw_ops;
210 clk_hw->hw.init = &init;
211
212 init.name = name;
213 init.ops = ops;
214 init.parent_names = &parent_name;
215 init.num_parents = 1;
216
217 /* register the clock */
218 clk = clk_register(NULL, &clk_hw->hw);
219
220 if (IS_ERR(clk)) {
221 kfree(clk_hw);
222 } else {
223 omap2_init_clk_hw_omap_clocks(clk);
224 of_clk_add_provider(node, of_clk_src_simple_get, clk);
225 }
226}
227#endif
228
229/**
230 * of_ti_dpll_setup - Setup function for OMAP DPLL clocks
231 * @node: device node containing the DPLL info
232 * @ops: ops for the DPLL
233 * @ddt: DPLL data template to use
Tero Kristof38b0dd2013-06-12 16:04:34 +0300234 *
235 * Initializes a DPLL clock from device tree data.
236 */
237static void __init of_ti_dpll_setup(struct device_node *node,
238 const struct clk_ops *ops,
Tero Kristoa6fe3772014-02-21 17:22:32 +0200239 const struct dpll_data *ddt)
Tero Kristof38b0dd2013-06-12 16:04:34 +0300240{
241 struct clk_hw_omap *clk_hw = NULL;
242 struct clk_init_data *init = NULL;
243 const char **parent_names = NULL;
244 struct dpll_data *dd = NULL;
245 int i;
246 u8 dpll_mode = 0;
247
248 dd = kzalloc(sizeof(*dd), GFP_KERNEL);
249 clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL);
250 init = kzalloc(sizeof(*init), GFP_KERNEL);
251 if (!dd || !clk_hw || !init)
252 goto cleanup;
253
254 memcpy(dd, ddt, sizeof(*dd));
255
256 clk_hw->dpll_data = dd;
257 clk_hw->ops = &clkhwops_omap3_dpll;
258 clk_hw->hw.init = init;
259 clk_hw->flags = MEMMAP_ADDRESSING;
260
261 init->name = node->name;
262 init->ops = ops;
263
264 init->num_parents = of_clk_get_parent_count(node);
265 if (init->num_parents < 1) {
266 pr_err("%s must have parent(s)\n", node->name);
267 goto cleanup;
268 }
269
270 parent_names = kzalloc(sizeof(char *) * init->num_parents, GFP_KERNEL);
271 if (!parent_names)
272 goto cleanup;
273
274 for (i = 0; i < init->num_parents; i++)
275 parent_names[i] = of_clk_get_parent_name(node, i);
276
277 init->parent_names = parent_names;
278
279 dd->control_reg = ti_clk_get_reg_addr(node, 0);
Tero Kristof38b0dd2013-06-12 16:04:34 +0300280
Tero Kristoaa76fcf2014-02-21 17:36:21 +0200281 /*
282 * Special case for OMAP2 DPLL, register order is different due to
283 * missing idlest_reg, also clkhwops is different. Detected from
284 * missing idlest_mask.
285 */
286 if (!dd->idlest_mask) {
287 dd->mult_div1_reg = ti_clk_get_reg_addr(node, 1);
288#ifdef CONFIG_ARCH_OMAP2
289 clk_hw->ops = &clkhwops_omap2xxx_dpll;
290 omap2xxx_clkt_dpllcore_init(&clk_hw->hw);
291#endif
292 } else {
293 dd->idlest_reg = ti_clk_get_reg_addr(node, 1);
294 if (!dd->idlest_reg)
295 goto cleanup;
296
297 dd->mult_div1_reg = ti_clk_get_reg_addr(node, 2);
298 }
299
300 if (!dd->control_reg || !dd->mult_div1_reg)
Tero Kristof38b0dd2013-06-12 16:04:34 +0300301 goto cleanup;
302
Tero Kristoa6fe3772014-02-21 17:22:32 +0200303 if (dd->autoidle_mask) {
Tero Kristof38b0dd2013-06-12 16:04:34 +0300304 dd->autoidle_reg = ti_clk_get_reg_addr(node, 3);
305 if (!dd->autoidle_reg)
306 goto cleanup;
307 }
308
309 if (of_property_read_bool(node, "ti,low-power-stop"))
310 dpll_mode |= 1 << DPLL_LOW_POWER_STOP;
311
312 if (of_property_read_bool(node, "ti,low-power-bypass"))
313 dpll_mode |= 1 << DPLL_LOW_POWER_BYPASS;
314
315 if (of_property_read_bool(node, "ti,lock"))
316 dpll_mode |= 1 << DPLL_LOCKED;
317
318 if (dpll_mode)
319 dd->modes = dpll_mode;
320
321 ti_clk_register_dpll(&clk_hw->hw, node);
322 return;
323
324cleanup:
325 kfree(dd);
326 kfree(parent_names);
327 kfree(init);
328 kfree(clk_hw);
329}
330
331#if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \
332 defined(CONFIG_SOC_DRA7XX)
333static void __init of_ti_omap4_dpll_x2_setup(struct device_node *node)
334{
335 ti_clk_register_dpll_x2(node, &dpll_x2_ck_ops, &clkhwops_omap4_dpllmx);
336}
337CLK_OF_DECLARE(ti_omap4_dpll_x2_clock, "ti,omap4-dpll-x2-clock",
338 of_ti_omap4_dpll_x2_setup);
339#endif
340
Roger Quadros4332ec12014-06-17 17:03:24 +0300341#if defined(CONFIG_SOC_AM33XX) || defined(CONFIG_SOC_AM43XX)
Tero Kristof38b0dd2013-06-12 16:04:34 +0300342static void __init of_ti_am3_dpll_x2_setup(struct device_node *node)
343{
344 ti_clk_register_dpll_x2(node, &dpll_x2_ck_ops, NULL);
345}
346CLK_OF_DECLARE(ti_am3_dpll_x2_clock, "ti,am3-dpll-x2-clock",
347 of_ti_am3_dpll_x2_setup);
348#endif
349
350#ifdef CONFIG_ARCH_OMAP3
351static void __init of_ti_omap3_dpll_setup(struct device_node *node)
352{
353 const struct dpll_data dd = {
354 .idlest_mask = 0x1,
355 .enable_mask = 0x7,
356 .autoidle_mask = 0x7,
357 .mult_mask = 0x7ff << 8,
358 .div1_mask = 0x7f,
359 .max_multiplier = 2047,
360 .max_divider = 128,
361 .min_divider = 1,
362 .freqsel_mask = 0xf0,
363 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
364 };
365
Tero Kristoa6fe3772014-02-21 17:22:32 +0200366 of_ti_dpll_setup(node, &omap3_dpll_ck_ops, &dd);
Tero Kristof38b0dd2013-06-12 16:04:34 +0300367}
368CLK_OF_DECLARE(ti_omap3_dpll_clock, "ti,omap3-dpll-clock",
369 of_ti_omap3_dpll_setup);
370
371static void __init of_ti_omap3_core_dpll_setup(struct device_node *node)
372{
373 const struct dpll_data dd = {
374 .idlest_mask = 0x1,
375 .enable_mask = 0x7,
376 .autoidle_mask = 0x7,
377 .mult_mask = 0x7ff << 16,
378 .div1_mask = 0x7f << 8,
379 .max_multiplier = 2047,
380 .max_divider = 128,
381 .min_divider = 1,
382 .freqsel_mask = 0xf0,
383 };
384
Tero Kristoa6fe3772014-02-21 17:22:32 +0200385 of_ti_dpll_setup(node, &omap3_dpll_core_ck_ops, &dd);
Tero Kristof38b0dd2013-06-12 16:04:34 +0300386}
387CLK_OF_DECLARE(ti_omap3_core_dpll_clock, "ti,omap3-dpll-core-clock",
388 of_ti_omap3_core_dpll_setup);
389
390static void __init of_ti_omap3_per_dpll_setup(struct device_node *node)
391{
392 const struct dpll_data dd = {
393 .idlest_mask = 0x1 << 1,
394 .enable_mask = 0x7 << 16,
395 .autoidle_mask = 0x7 << 3,
396 .mult_mask = 0x7ff << 8,
397 .div1_mask = 0x7f,
398 .max_multiplier = 2047,
399 .max_divider = 128,
400 .min_divider = 1,
401 .freqsel_mask = 0xf00000,
402 .modes = (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED),
403 };
404
Tero Kristoa6fe3772014-02-21 17:22:32 +0200405 of_ti_dpll_setup(node, &omap3_dpll_per_ck_ops, &dd);
Tero Kristof38b0dd2013-06-12 16:04:34 +0300406}
407CLK_OF_DECLARE(ti_omap3_per_dpll_clock, "ti,omap3-dpll-per-clock",
408 of_ti_omap3_per_dpll_setup);
409
410static void __init of_ti_omap3_per_jtype_dpll_setup(struct device_node *node)
411{
412 const struct dpll_data dd = {
413 .idlest_mask = 0x1 << 1,
414 .enable_mask = 0x7 << 16,
415 .autoidle_mask = 0x7 << 3,
416 .mult_mask = 0xfff << 8,
417 .div1_mask = 0x7f,
418 .max_multiplier = 4095,
419 .max_divider = 128,
420 .min_divider = 1,
421 .sddiv_mask = 0xff << 24,
422 .dco_mask = 0xe << 20,
423 .flags = DPLL_J_TYPE,
424 .modes = (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED),
425 };
426
Tero Kristoa6fe3772014-02-21 17:22:32 +0200427 of_ti_dpll_setup(node, &omap3_dpll_per_ck_ops, &dd);
Tero Kristof38b0dd2013-06-12 16:04:34 +0300428}
429CLK_OF_DECLARE(ti_omap3_per_jtype_dpll_clock, "ti,omap3-dpll-per-j-type-clock",
430 of_ti_omap3_per_jtype_dpll_setup);
431#endif
432
433static void __init of_ti_omap4_dpll_setup(struct device_node *node)
434{
435 const struct dpll_data dd = {
436 .idlest_mask = 0x1,
437 .enable_mask = 0x7,
438 .autoidle_mask = 0x7,
439 .mult_mask = 0x7ff << 8,
440 .div1_mask = 0x7f,
441 .max_multiplier = 2047,
442 .max_divider = 128,
443 .min_divider = 1,
444 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
445 };
446
Tero Kristoa6fe3772014-02-21 17:22:32 +0200447 of_ti_dpll_setup(node, &dpll_ck_ops, &dd);
Tero Kristof38b0dd2013-06-12 16:04:34 +0300448}
449CLK_OF_DECLARE(ti_omap4_dpll_clock, "ti,omap4-dpll-clock",
450 of_ti_omap4_dpll_setup);
451
Nishanth Menonb4be0182014-05-16 05:45:59 -0500452static void __init of_ti_omap5_mpu_dpll_setup(struct device_node *node)
453{
454 const struct dpll_data dd = {
455 .idlest_mask = 0x1,
456 .enable_mask = 0x7,
457 .autoidle_mask = 0x7,
458 .mult_mask = 0x7ff << 8,
459 .div1_mask = 0x7f,
460 .max_multiplier = 2047,
461 .max_divider = 128,
462 .dcc_mask = BIT(22),
463 .dcc_rate = 1400000000, /* DCC beyond 1.4GHz */
464 .min_divider = 1,
465 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
466 };
467
468 of_ti_dpll_setup(node, &dpll_ck_ops, &dd);
469}
470CLK_OF_DECLARE(of_ti_omap5_mpu_dpll_clock, "ti,omap5-mpu-dpll-clock",
471 of_ti_omap5_mpu_dpll_setup);
472
Tero Kristof38b0dd2013-06-12 16:04:34 +0300473static void __init of_ti_omap4_core_dpll_setup(struct device_node *node)
474{
475 const struct dpll_data dd = {
476 .idlest_mask = 0x1,
477 .enable_mask = 0x7,
478 .autoidle_mask = 0x7,
479 .mult_mask = 0x7ff << 8,
480 .div1_mask = 0x7f,
481 .max_multiplier = 2047,
482 .max_divider = 128,
483 .min_divider = 1,
484 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
485 };
486
Tero Kristoa6fe3772014-02-21 17:22:32 +0200487 of_ti_dpll_setup(node, &dpll_core_ck_ops, &dd);
Tero Kristof38b0dd2013-06-12 16:04:34 +0300488}
489CLK_OF_DECLARE(ti_omap4_core_dpll_clock, "ti,omap4-dpll-core-clock",
490 of_ti_omap4_core_dpll_setup);
491
492#if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \
493 defined(CONFIG_SOC_DRA7XX)
494static void __init of_ti_omap4_m4xen_dpll_setup(struct device_node *node)
495{
496 const struct dpll_data dd = {
497 .idlest_mask = 0x1,
498 .enable_mask = 0x7,
499 .autoidle_mask = 0x7,
500 .mult_mask = 0x7ff << 8,
501 .div1_mask = 0x7f,
502 .max_multiplier = 2047,
503 .max_divider = 128,
504 .min_divider = 1,
505 .m4xen_mask = 0x800,
506 .lpmode_mask = 1 << 10,
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_m4xen_ck_ops, &dd);
Tero Kristof38b0dd2013-06-12 16:04:34 +0300511}
512CLK_OF_DECLARE(ti_omap4_m4xen_dpll_clock, "ti,omap4-dpll-m4xen-clock",
513 of_ti_omap4_m4xen_dpll_setup);
514
515static void __init of_ti_omap4_jtype_dpll_setup(struct device_node *node)
516{
517 const struct dpll_data dd = {
518 .idlest_mask = 0x1,
519 .enable_mask = 0x7,
520 .autoidle_mask = 0x7,
521 .mult_mask = 0xfff << 8,
522 .div1_mask = 0xff,
523 .max_multiplier = 4095,
524 .max_divider = 256,
525 .min_divider = 1,
526 .sddiv_mask = 0xff << 24,
527 .flags = DPLL_J_TYPE,
528 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
529 };
530
Tero Kristoa6fe3772014-02-21 17:22:32 +0200531 of_ti_dpll_setup(node, &dpll_m4xen_ck_ops, &dd);
Tero Kristof38b0dd2013-06-12 16:04:34 +0300532}
533CLK_OF_DECLARE(ti_omap4_jtype_dpll_clock, "ti,omap4-dpll-j-type-clock",
534 of_ti_omap4_jtype_dpll_setup);
535#endif
536
537static void __init of_ti_am3_no_gate_dpll_setup(struct device_node *node)
538{
539 const struct dpll_data dd = {
540 .idlest_mask = 0x1,
541 .enable_mask = 0x7,
Tero Kristof38b0dd2013-06-12 16:04:34 +0300542 .mult_mask = 0x7ff << 8,
543 .div1_mask = 0x7f,
544 .max_multiplier = 2047,
545 .max_divider = 128,
546 .min_divider = 1,
547 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
548 };
549
Tero Kristoa6fe3772014-02-21 17:22:32 +0200550 of_ti_dpll_setup(node, &dpll_no_gate_ck_ops, &dd);
Tero Kristof38b0dd2013-06-12 16:04:34 +0300551}
552CLK_OF_DECLARE(ti_am3_no_gate_dpll_clock, "ti,am3-dpll-no-gate-clock",
553 of_ti_am3_no_gate_dpll_setup);
554
555static void __init of_ti_am3_jtype_dpll_setup(struct device_node *node)
556{
557 const struct dpll_data dd = {
558 .idlest_mask = 0x1,
559 .enable_mask = 0x7,
Tero Kristof38b0dd2013-06-12 16:04:34 +0300560 .mult_mask = 0x7ff << 8,
561 .div1_mask = 0x7f,
562 .max_multiplier = 4095,
563 .max_divider = 256,
564 .min_divider = 2,
565 .flags = DPLL_J_TYPE,
566 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
567 };
568
Tero Kristoa6fe3772014-02-21 17:22:32 +0200569 of_ti_dpll_setup(node, &dpll_ck_ops, &dd);
Tero Kristof38b0dd2013-06-12 16:04:34 +0300570}
571CLK_OF_DECLARE(ti_am3_jtype_dpll_clock, "ti,am3-dpll-j-type-clock",
572 of_ti_am3_jtype_dpll_setup);
573
574static void __init of_ti_am3_no_gate_jtype_dpll_setup(struct device_node *node)
575{
576 const struct dpll_data dd = {
577 .idlest_mask = 0x1,
578 .enable_mask = 0x7,
Tero Kristof38b0dd2013-06-12 16:04:34 +0300579 .mult_mask = 0x7ff << 8,
580 .div1_mask = 0x7f,
581 .max_multiplier = 2047,
582 .max_divider = 128,
583 .min_divider = 1,
584 .flags = DPLL_J_TYPE,
585 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
586 };
587
Tero Kristoa6fe3772014-02-21 17:22:32 +0200588 of_ti_dpll_setup(node, &dpll_no_gate_ck_ops, &dd);
Tero Kristof38b0dd2013-06-12 16:04:34 +0300589}
590CLK_OF_DECLARE(ti_am3_no_gate_jtype_dpll_clock,
591 "ti,am3-dpll-no-gate-j-type-clock",
592 of_ti_am3_no_gate_jtype_dpll_setup);
593
594static void __init of_ti_am3_dpll_setup(struct device_node *node)
595{
596 const struct dpll_data dd = {
597 .idlest_mask = 0x1,
598 .enable_mask = 0x7,
Tero Kristof38b0dd2013-06-12 16:04:34 +0300599 .mult_mask = 0x7ff << 8,
600 .div1_mask = 0x7f,
601 .max_multiplier = 2047,
602 .max_divider = 128,
603 .min_divider = 1,
604 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
605 };
606
Tero Kristoa6fe3772014-02-21 17:22:32 +0200607 of_ti_dpll_setup(node, &dpll_ck_ops, &dd);
Tero Kristof38b0dd2013-06-12 16:04:34 +0300608}
609CLK_OF_DECLARE(ti_am3_dpll_clock, "ti,am3-dpll-clock", of_ti_am3_dpll_setup);
610
611static void __init of_ti_am3_core_dpll_setup(struct device_node *node)
612{
613 const struct dpll_data dd = {
614 .idlest_mask = 0x1,
615 .enable_mask = 0x7,
Tero Kristof38b0dd2013-06-12 16:04:34 +0300616 .mult_mask = 0x7ff << 8,
617 .div1_mask = 0x7f,
618 .max_multiplier = 2047,
619 .max_divider = 128,
620 .min_divider = 1,
621 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
622 };
623
Tero Kristoa6fe3772014-02-21 17:22:32 +0200624 of_ti_dpll_setup(node, &dpll_core_ck_ops, &dd);
Tero Kristof38b0dd2013-06-12 16:04:34 +0300625}
626CLK_OF_DECLARE(ti_am3_core_dpll_clock, "ti,am3-dpll-core-clock",
627 of_ti_am3_core_dpll_setup);
Tero Kristoaa76fcf2014-02-21 17:36:21 +0200628
629static void __init of_ti_omap2_core_dpll_setup(struct device_node *node)
630{
631 const struct dpll_data dd = {
632 .enable_mask = 0x3,
633 .mult_mask = 0x3ff << 12,
634 .div1_mask = 0xf << 8,
635 .max_divider = 16,
636 .min_divider = 1,
637 };
638
639 of_ti_dpll_setup(node, &omap2_dpll_core_ck_ops, &dd);
640}
641CLK_OF_DECLARE(ti_omap2_core_dpll_clock, "ti,omap2-dpll-core-clock",
642 of_ti_omap2_core_dpll_setup);