1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * OMAP DPLL clock support
4 *
5 * Copyright (C) 2013 Texas Instruments, Inc.
6 *
7 * Tero Kristo <t-kristo@ti.com>
8 */
9
10 #include <linux/clk.h>
11 #include <linux/clk-provider.h>
12 #include <linux/slab.h>
13 #include <linux/err.h>
14 #include <linux/of.h>
15 #include <linux/of_address.h>
16 #include <linux/clk/ti.h>
17 #include "clock.h"
18
19 #undef pr_fmt
20 #define pr_fmt(fmt) "%s: " fmt, __func__
21
22 #if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \
23 defined(CONFIG_SOC_DRA7XX)
24 static const struct clk_ops dpll_m4xen_ck_ops = {
25 .enable = &omap3_noncore_dpll_enable,
26 .disable = &omap3_noncore_dpll_disable,
27 .recalc_rate = &omap4_dpll_regm4xen_recalc,
28 .round_rate = &omap4_dpll_regm4xen_round_rate,
29 .set_rate = &omap3_noncore_dpll_set_rate,
30 .set_parent = &omap3_noncore_dpll_set_parent,
31 .set_rate_and_parent = &omap3_noncore_dpll_set_rate_and_parent,
32 .determine_rate = &omap4_dpll_regm4xen_determine_rate,
33 .get_parent = &omap2_init_dpll_parent,
34 .save_context = &omap3_core_dpll_save_context,
35 .restore_context = &omap3_core_dpll_restore_context,
36 };
37 #endif
38
39 #if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4) || \
40 defined(CONFIG_SOC_OMAP5) || defined(CONFIG_SOC_DRA7XX) || \
41 defined(CONFIG_SOC_AM33XX) || defined(CONFIG_SOC_AM43XX)
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 static const struct clk_ops dpll_ck_ops = {
48 .enable = &omap3_noncore_dpll_enable,
49 .disable = &omap3_noncore_dpll_disable,
50 .recalc_rate = &omap3_dpll_recalc,
51 .round_rate = &omap2_dpll_round_rate,
52 .set_rate = &omap3_noncore_dpll_set_rate,
53 .set_parent = &omap3_noncore_dpll_set_parent,
54 .set_rate_and_parent = &omap3_noncore_dpll_set_rate_and_parent,
55 .determine_rate = &omap3_noncore_dpll_determine_rate,
56 .get_parent = &omap2_init_dpll_parent,
57 .save_context = &omap3_noncore_dpll_save_context,
58 .restore_context = &omap3_noncore_dpll_restore_context,
59 };
60
61 static const struct clk_ops dpll_no_gate_ck_ops = {
62 .recalc_rate = &omap3_dpll_recalc,
63 .get_parent = &omap2_init_dpll_parent,
64 .round_rate = &omap2_dpll_round_rate,
65 .set_rate = &omap3_noncore_dpll_set_rate,
66 .set_parent = &omap3_noncore_dpll_set_parent,
67 .set_rate_and_parent = &omap3_noncore_dpll_set_rate_and_parent,
68 .determine_rate = &omap3_noncore_dpll_determine_rate,
69 .save_context = &omap3_noncore_dpll_save_context,
70 .restore_context = &omap3_noncore_dpll_restore_context
71 };
72 #else
73 static const struct clk_ops dpll_core_ck_ops = {};
74 static const struct clk_ops dpll_ck_ops = {};
75 static const struct clk_ops dpll_no_gate_ck_ops = {};
76 const struct clk_hw_omap_ops clkhwops_omap3_dpll = {};
77 #endif
78
79 #ifdef CONFIG_ARCH_OMAP2
80 static const struct clk_ops omap2_dpll_core_ck_ops = {
81 .get_parent = &omap2_init_dpll_parent,
82 .recalc_rate = &omap2_dpllcore_recalc,
83 .round_rate = &omap2_dpll_round_rate,
84 .set_rate = &omap2_reprogram_dpllcore,
85 };
86 #else
87 static const struct clk_ops omap2_dpll_core_ck_ops = {};
88 #endif
89
90 #ifdef CONFIG_ARCH_OMAP3
91 static const struct clk_ops omap3_dpll_core_ck_ops = {
92 .get_parent = &omap2_init_dpll_parent,
93 .recalc_rate = &omap3_dpll_recalc,
94 .round_rate = &omap2_dpll_round_rate,
95 };
96
97 static const struct clk_ops omap3_dpll_ck_ops = {
98 .enable = &omap3_noncore_dpll_enable,
99 .disable = &omap3_noncore_dpll_disable,
100 .get_parent = &omap2_init_dpll_parent,
101 .recalc_rate = &omap3_dpll_recalc,
102 .set_rate = &omap3_noncore_dpll_set_rate,
103 .set_parent = &omap3_noncore_dpll_set_parent,
104 .set_rate_and_parent = &omap3_noncore_dpll_set_rate_and_parent,
105 .determine_rate = &omap3_noncore_dpll_determine_rate,
106 .round_rate = &omap2_dpll_round_rate,
107 };
108
109 static const struct clk_ops omap3_dpll5_ck_ops = {
110 .enable = &omap3_noncore_dpll_enable,
111 .disable = &omap3_noncore_dpll_disable,
112 .get_parent = &omap2_init_dpll_parent,
113 .recalc_rate = &omap3_dpll_recalc,
114 .set_rate = &omap3_dpll5_set_rate,
115 .set_parent = &omap3_noncore_dpll_set_parent,
116 .set_rate_and_parent = &omap3_noncore_dpll_set_rate_and_parent,
117 .determine_rate = &omap3_noncore_dpll_determine_rate,
118 .round_rate = &omap2_dpll_round_rate,
119 };
120
121 static const struct clk_ops omap3_dpll_per_ck_ops = {
122 .enable = &omap3_noncore_dpll_enable,
123 .disable = &omap3_noncore_dpll_disable,
124 .get_parent = &omap2_init_dpll_parent,
125 .recalc_rate = &omap3_dpll_recalc,
126 .set_rate = &omap3_dpll4_set_rate,
127 .set_parent = &omap3_noncore_dpll_set_parent,
128 .set_rate_and_parent = &omap3_dpll4_set_rate_and_parent,
129 .determine_rate = &omap3_noncore_dpll_determine_rate,
130 .round_rate = &omap2_dpll_round_rate,
131 };
132 #endif
133
134 #if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \
135 defined(CONFIG_SOC_DRA7XX) || defined(CONFIG_SOC_AM33XX) || \
136 defined(CONFIG_SOC_AM43XX)
137 static const struct clk_ops dpll_x2_ck_ops = {
138 .recalc_rate = &omap3_clkoutx2_recalc,
139 };
140 #endif
141
142 /**
143 * _register_dpll - low level registration of a DPLL clock
144 * @user: pointer to the hardware clock definition for the clock
145 * @node: device node for the clock
146 *
147 * Finalizes DPLL registration process. In case a failure (clk-ref or
148 * clk-bypass is missing), the clock is added to retry list and
149 * the initialization is retried on later stage.
150 */
_register_dpll(void * user,struct device_node * node)151 static void __init _register_dpll(void *user,
152 struct device_node *node)
153 {
154 struct clk_hw *hw = user;
155 struct clk_hw_omap *clk_hw = to_clk_hw_omap(hw);
156 struct dpll_data *dd = clk_hw->dpll_data;
157 const char *name;
158 struct clk *clk;
159 const struct clk_init_data *init = hw->init;
160
161 clk = of_clk_get(node, 0);
162 if (IS_ERR(clk)) {
163 pr_debug("clk-ref missing for %pOFn, retry later\n",
164 node);
165 if (!ti_clk_retry_init(node, hw, _register_dpll))
166 return;
167
168 goto cleanup;
169 }
170
171 dd->clk_ref = __clk_get_hw(clk);
172
173 clk = of_clk_get(node, 1);
174
175 if (IS_ERR(clk)) {
176 pr_debug("clk-bypass missing for %pOFn, retry later\n",
177 node);
178 if (!ti_clk_retry_init(node, hw, _register_dpll))
179 return;
180
181 goto cleanup;
182 }
183
184 dd->clk_bypass = __clk_get_hw(clk);
185
186 /* register the clock */
187 name = ti_dt_clk_name(node);
188 clk = of_ti_clk_register_omap_hw(node, &clk_hw->hw, name);
189
190 if (!IS_ERR(clk)) {
191 of_clk_add_provider(node, of_clk_src_simple_get, clk);
192 kfree(init->parent_names);
193 kfree(init);
194 return;
195 }
196
197 cleanup:
198 kfree(clk_hw->dpll_data);
199 kfree(init->parent_names);
200 kfree(init);
201 kfree(clk_hw);
202 }
203
204 #if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \
205 defined(CONFIG_SOC_DRA7XX) || defined(CONFIG_SOC_AM33XX) || \
206 defined(CONFIG_SOC_AM43XX)
207 /**
208 * _register_dpll_x2 - Registers a DPLLx2 clock
209 * @node: device node for this clock
210 * @ops: clk_ops for this clock
211 * @hw_ops: clk_hw_ops for this clock
212 *
213 * Initializes a DPLL x 2 clock from device tree data.
214 */
_register_dpll_x2(struct device_node * node,const struct clk_ops * ops,const struct clk_hw_omap_ops * hw_ops)215 static void _register_dpll_x2(struct device_node *node,
216 const struct clk_ops *ops,
217 const struct clk_hw_omap_ops *hw_ops)
218 {
219 struct clk *clk;
220 struct clk_init_data init = { NULL };
221 struct clk_hw_omap *clk_hw;
222 const char *name = ti_dt_clk_name(node);
223 const char *parent_name;
224
225 parent_name = of_clk_get_parent_name(node, 0);
226 if (!parent_name) {
227 pr_err("%pOFn must have parent\n", node);
228 return;
229 }
230
231 clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL);
232 if (!clk_hw)
233 return;
234
235 clk_hw->ops = hw_ops;
236 clk_hw->hw.init = &init;
237
238 init.name = name;
239 init.ops = ops;
240 init.parent_names = &parent_name;
241 init.num_parents = 1;
242
243 #if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \
244 defined(CONFIG_SOC_DRA7XX)
245 if (hw_ops == &clkhwops_omap4_dpllmx) {
246 int ret;
247
248 /* Check if register defined, if not, drop hw-ops */
249 ret = of_property_count_elems_of_size(node, "reg", 1);
250 if (ret <= 0) {
251 clk_hw->ops = NULL;
252 } else if (ti_clk_get_reg_addr(node, 0, &clk_hw->clksel_reg)) {
253 kfree(clk_hw);
254 return;
255 }
256 }
257 #endif
258
259 /* register the clock */
260 clk = of_ti_clk_register_omap_hw(node, &clk_hw->hw, name);
261
262 if (IS_ERR(clk))
263 kfree(clk_hw);
264 else
265 of_clk_add_provider(node, of_clk_src_simple_get, clk);
266 }
267 #endif
268
269 /**
270 * of_ti_dpll_setup - Setup function for OMAP DPLL clocks
271 * @node: device node containing the DPLL info
272 * @ops: ops for the DPLL
273 * @ddt: DPLL data template to use
274 *
275 * Initializes a DPLL clock from device tree data.
276 */
of_ti_dpll_setup(struct device_node * node,const struct clk_ops * ops,const struct dpll_data * ddt)277 static void __init of_ti_dpll_setup(struct device_node *node,
278 const struct clk_ops *ops,
279 const struct dpll_data *ddt)
280 {
281 struct clk_hw_omap *clk_hw = NULL;
282 struct clk_init_data *init = NULL;
283 const char **parent_names = NULL;
284 struct dpll_data *dd = NULL;
285 int ssc_clk_index;
286 u8 dpll_mode = 0;
287 u32 min_div;
288
289 dd = kmemdup(ddt, sizeof(*dd), GFP_KERNEL);
290 clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL);
291 init = kzalloc(sizeof(*init), GFP_KERNEL);
292 if (!dd || !clk_hw || !init)
293 goto cleanup;
294
295 clk_hw->dpll_data = dd;
296 clk_hw->ops = &clkhwops_omap3_dpll;
297 clk_hw->hw.init = init;
298
299 init->name = ti_dt_clk_name(node);
300 init->ops = ops;
301
302 init->num_parents = of_clk_get_parent_count(node);
303 if (!init->num_parents) {
304 pr_err("%pOFn must have parent(s)\n", node);
305 goto cleanup;
306 }
307
308 parent_names = kcalloc(init->num_parents, sizeof(char *), GFP_KERNEL);
309 if (!parent_names)
310 goto cleanup;
311
312 of_clk_parent_fill(node, parent_names, init->num_parents);
313
314 init->parent_names = parent_names;
315
316 if (ti_clk_get_reg_addr(node, 0, &dd->control_reg))
317 goto cleanup;
318
319 /*
320 * Special case for OMAP2 DPLL, register order is different due to
321 * missing idlest_reg, also clkhwops is different. Detected from
322 * missing idlest_mask.
323 */
324 if (!dd->idlest_mask) {
325 if (ti_clk_get_reg_addr(node, 1, &dd->mult_div1_reg))
326 goto cleanup;
327 #ifdef CONFIG_ARCH_OMAP2
328 clk_hw->ops = &clkhwops_omap2xxx_dpll;
329 omap2xxx_clkt_dpllcore_init(&clk_hw->hw);
330 #endif
331 } else {
332 if (ti_clk_get_reg_addr(node, 1, &dd->idlest_reg))
333 goto cleanup;
334
335 if (ti_clk_get_reg_addr(node, 2, &dd->mult_div1_reg))
336 goto cleanup;
337 }
338
339 if (dd->autoidle_mask) {
340 if (ti_clk_get_reg_addr(node, 3, &dd->autoidle_reg))
341 goto cleanup;
342
343 ssc_clk_index = 4;
344 } else {
345 ssc_clk_index = 3;
346 }
347
348 if (dd->ssc_deltam_int_mask && dd->ssc_deltam_frac_mask &&
349 dd->ssc_modfreq_mant_mask && dd->ssc_modfreq_exp_mask) {
350 if (ti_clk_get_reg_addr(node, ssc_clk_index++,
351 &dd->ssc_deltam_reg))
352 goto cleanup;
353
354 if (ti_clk_get_reg_addr(node, ssc_clk_index++,
355 &dd->ssc_modfreq_reg))
356 goto cleanup;
357
358 of_property_read_u32(node, "ti,ssc-modfreq-hz",
359 &dd->ssc_modfreq);
360 of_property_read_u32(node, "ti,ssc-deltam", &dd->ssc_deltam);
361 dd->ssc_downspread =
362 of_property_read_bool(node, "ti,ssc-downspread");
363 }
364
365 if (of_property_read_bool(node, "ti,low-power-stop"))
366 dpll_mode |= 1 << DPLL_LOW_POWER_STOP;
367
368 if (of_property_read_bool(node, "ti,low-power-bypass"))
369 dpll_mode |= 1 << DPLL_LOW_POWER_BYPASS;
370
371 if (of_property_read_bool(node, "ti,lock"))
372 dpll_mode |= 1 << DPLL_LOCKED;
373
374 if (!of_property_read_u32(node, "ti,min-div", &min_div) &&
375 min_div > dd->min_divider)
376 dd->min_divider = min_div;
377
378 if (dpll_mode)
379 dd->modes = dpll_mode;
380
381 _register_dpll(&clk_hw->hw, node);
382 return;
383
384 cleanup:
385 kfree(dd);
386 kfree(parent_names);
387 kfree(init);
388 kfree(clk_hw);
389 }
390
391 #if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \
392 defined(CONFIG_SOC_DRA7XX)
of_ti_omap4_dpll_x2_setup(struct device_node * node)393 static void __init of_ti_omap4_dpll_x2_setup(struct device_node *node)
394 {
395 _register_dpll_x2(node, &dpll_x2_ck_ops, &clkhwops_omap4_dpllmx);
396 }
397 CLK_OF_DECLARE(ti_omap4_dpll_x2_clock, "ti,omap4-dpll-x2-clock",
398 of_ti_omap4_dpll_x2_setup);
399 #endif
400
401 #if defined(CONFIG_SOC_AM33XX) || defined(CONFIG_SOC_AM43XX)
of_ti_am3_dpll_x2_setup(struct device_node * node)402 static void __init of_ti_am3_dpll_x2_setup(struct device_node *node)
403 {
404 _register_dpll_x2(node, &dpll_x2_ck_ops, NULL);
405 }
406 CLK_OF_DECLARE(ti_am3_dpll_x2_clock, "ti,am3-dpll-x2-clock",
407 of_ti_am3_dpll_x2_setup);
408 #endif
409
410 #ifdef CONFIG_ARCH_OMAP3
of_ti_omap3_dpll_setup(struct device_node * node)411 static void __init of_ti_omap3_dpll_setup(struct device_node *node)
412 {
413 const struct dpll_data dd = {
414 .idlest_mask = 0x1,
415 .enable_mask = 0x7,
416 .autoidle_mask = 0x7,
417 .mult_mask = 0x7ff << 8,
418 .div1_mask = 0x7f,
419 .max_multiplier = 2047,
420 .max_divider = 128,
421 .min_divider = 1,
422 .freqsel_mask = 0xf0,
423 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
424 };
425
426 if ((of_machine_is_compatible("ti,omap3630") ||
427 of_machine_is_compatible("ti,omap36xx")) &&
428 of_node_name_eq(node, "dpll5_ck"))
429 of_ti_dpll_setup(node, &omap3_dpll5_ck_ops, &dd);
430 else
431 of_ti_dpll_setup(node, &omap3_dpll_ck_ops, &dd);
432 }
433 CLK_OF_DECLARE(ti_omap3_dpll_clock, "ti,omap3-dpll-clock",
434 of_ti_omap3_dpll_setup);
435
of_ti_omap3_core_dpll_setup(struct device_node * node)436 static void __init of_ti_omap3_core_dpll_setup(struct device_node *node)
437 {
438 const struct dpll_data dd = {
439 .idlest_mask = 0x1,
440 .enable_mask = 0x7,
441 .autoidle_mask = 0x7,
442 .mult_mask = 0x7ff << 16,
443 .div1_mask = 0x7f << 8,
444 .max_multiplier = 2047,
445 .max_divider = 128,
446 .min_divider = 1,
447 .freqsel_mask = 0xf0,
448 };
449
450 of_ti_dpll_setup(node, &omap3_dpll_core_ck_ops, &dd);
451 }
452 CLK_OF_DECLARE(ti_omap3_core_dpll_clock, "ti,omap3-dpll-core-clock",
453 of_ti_omap3_core_dpll_setup);
454
of_ti_omap3_per_dpll_setup(struct device_node * node)455 static void __init of_ti_omap3_per_dpll_setup(struct device_node *node)
456 {
457 const struct dpll_data dd = {
458 .idlest_mask = 0x1 << 1,
459 .enable_mask = 0x7 << 16,
460 .autoidle_mask = 0x7 << 3,
461 .mult_mask = 0x7ff << 8,
462 .div1_mask = 0x7f,
463 .max_multiplier = 2047,
464 .max_divider = 128,
465 .min_divider = 1,
466 .freqsel_mask = 0xf00000,
467 .modes = (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED),
468 };
469
470 of_ti_dpll_setup(node, &omap3_dpll_per_ck_ops, &dd);
471 }
472 CLK_OF_DECLARE(ti_omap3_per_dpll_clock, "ti,omap3-dpll-per-clock",
473 of_ti_omap3_per_dpll_setup);
474
of_ti_omap3_per_jtype_dpll_setup(struct device_node * node)475 static void __init of_ti_omap3_per_jtype_dpll_setup(struct device_node *node)
476 {
477 const struct dpll_data dd = {
478 .idlest_mask = 0x1 << 1,
479 .enable_mask = 0x7 << 16,
480 .autoidle_mask = 0x7 << 3,
481 .mult_mask = 0xfff << 8,
482 .div1_mask = 0x7f,
483 .max_multiplier = 4095,
484 .max_divider = 128,
485 .min_divider = 1,
486 .sddiv_mask = 0xff << 24,
487 .dco_mask = 0xe << 20,
488 .flags = DPLL_J_TYPE,
489 .modes = (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED),
490 };
491
492 of_ti_dpll_setup(node, &omap3_dpll_per_ck_ops, &dd);
493 }
494 CLK_OF_DECLARE(ti_omap3_per_jtype_dpll_clock, "ti,omap3-dpll-per-j-type-clock",
495 of_ti_omap3_per_jtype_dpll_setup);
496 #endif
497
of_ti_omap4_dpll_setup(struct device_node * node)498 static void __init of_ti_omap4_dpll_setup(struct device_node *node)
499 {
500 const struct dpll_data dd = {
501 .idlest_mask = 0x1,
502 .enable_mask = 0x7,
503 .autoidle_mask = 0x7,
504 .mult_mask = 0x7ff << 8,
505 .div1_mask = 0x7f,
506 .max_multiplier = 2047,
507 .max_divider = 128,
508 .min_divider = 1,
509 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
510 };
511
512 of_ti_dpll_setup(node, &dpll_ck_ops, &dd);
513 }
514 CLK_OF_DECLARE(ti_omap4_dpll_clock, "ti,omap4-dpll-clock",
515 of_ti_omap4_dpll_setup);
516
of_ti_omap5_mpu_dpll_setup(struct device_node * node)517 static void __init of_ti_omap5_mpu_dpll_setup(struct device_node *node)
518 {
519 const struct dpll_data dd = {
520 .idlest_mask = 0x1,
521 .enable_mask = 0x7,
522 .autoidle_mask = 0x7,
523 .mult_mask = 0x7ff << 8,
524 .div1_mask = 0x7f,
525 .max_multiplier = 2047,
526 .max_divider = 128,
527 .dcc_mask = BIT(22),
528 .dcc_rate = 1400000000, /* DCC beyond 1.4GHz */
529 .min_divider = 1,
530 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
531 };
532
533 of_ti_dpll_setup(node, &dpll_ck_ops, &dd);
534 }
535 CLK_OF_DECLARE(of_ti_omap5_mpu_dpll_clock, "ti,omap5-mpu-dpll-clock",
536 of_ti_omap5_mpu_dpll_setup);
537
of_ti_omap4_core_dpll_setup(struct device_node * node)538 static void __init of_ti_omap4_core_dpll_setup(struct device_node *node)
539 {
540 const struct dpll_data dd = {
541 .idlest_mask = 0x1,
542 .enable_mask = 0x7,
543 .autoidle_mask = 0x7,
544 .mult_mask = 0x7ff << 8,
545 .div1_mask = 0x7f,
546 .max_multiplier = 2047,
547 .max_divider = 128,
548 .min_divider = 1,
549 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
550 };
551
552 of_ti_dpll_setup(node, &dpll_core_ck_ops, &dd);
553 }
554 CLK_OF_DECLARE(ti_omap4_core_dpll_clock, "ti,omap4-dpll-core-clock",
555 of_ti_omap4_core_dpll_setup);
556
557 #if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \
558 defined(CONFIG_SOC_DRA7XX)
of_ti_omap4_m4xen_dpll_setup(struct device_node * node)559 static void __init of_ti_omap4_m4xen_dpll_setup(struct device_node *node)
560 {
561 const struct dpll_data dd = {
562 .idlest_mask = 0x1,
563 .enable_mask = 0x7,
564 .autoidle_mask = 0x7,
565 .mult_mask = 0x7ff << 8,
566 .div1_mask = 0x7f,
567 .max_multiplier = 2047,
568 .max_divider = 128,
569 .min_divider = 1,
570 .m4xen_mask = 0x800,
571 .lpmode_mask = 1 << 10,
572 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
573 };
574
575 of_ti_dpll_setup(node, &dpll_m4xen_ck_ops, &dd);
576 }
577 CLK_OF_DECLARE(ti_omap4_m4xen_dpll_clock, "ti,omap4-dpll-m4xen-clock",
578 of_ti_omap4_m4xen_dpll_setup);
579
of_ti_omap4_jtype_dpll_setup(struct device_node * node)580 static void __init of_ti_omap4_jtype_dpll_setup(struct device_node *node)
581 {
582 const struct dpll_data dd = {
583 .idlest_mask = 0x1,
584 .enable_mask = 0x7,
585 .autoidle_mask = 0x7,
586 .mult_mask = 0xfff << 8,
587 .div1_mask = 0xff,
588 .max_multiplier = 4095,
589 .max_divider = 256,
590 .min_divider = 1,
591 .sddiv_mask = 0xff << 24,
592 .flags = DPLL_J_TYPE,
593 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
594 };
595
596 of_ti_dpll_setup(node, &dpll_m4xen_ck_ops, &dd);
597 }
598 CLK_OF_DECLARE(ti_omap4_jtype_dpll_clock, "ti,omap4-dpll-j-type-clock",
599 of_ti_omap4_jtype_dpll_setup);
600 #endif
601
of_ti_am3_no_gate_dpll_setup(struct device_node * node)602 static void __init of_ti_am3_no_gate_dpll_setup(struct device_node *node)
603 {
604 const struct dpll_data dd = {
605 .idlest_mask = 0x1,
606 .enable_mask = 0x7,
607 .ssc_enable_mask = 0x1 << 12,
608 .ssc_downspread_mask = 0x1 << 14,
609 .mult_mask = 0x7ff << 8,
610 .div1_mask = 0x7f,
611 .ssc_deltam_int_mask = 0x3 << 18,
612 .ssc_deltam_frac_mask = 0x3ffff,
613 .ssc_modfreq_mant_mask = 0x7f,
614 .ssc_modfreq_exp_mask = 0x7 << 8,
615 .max_multiplier = 2047,
616 .max_divider = 128,
617 .min_divider = 1,
618 .max_rate = 1000000000,
619 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
620 };
621
622 of_ti_dpll_setup(node, &dpll_no_gate_ck_ops, &dd);
623 }
624 CLK_OF_DECLARE(ti_am3_no_gate_dpll_clock, "ti,am3-dpll-no-gate-clock",
625 of_ti_am3_no_gate_dpll_setup);
626
of_ti_am3_jtype_dpll_setup(struct device_node * node)627 static void __init of_ti_am3_jtype_dpll_setup(struct device_node *node)
628 {
629 const struct dpll_data dd = {
630 .idlest_mask = 0x1,
631 .enable_mask = 0x7,
632 .mult_mask = 0x7ff << 8,
633 .div1_mask = 0x7f,
634 .max_multiplier = 4095,
635 .max_divider = 256,
636 .min_divider = 2,
637 .flags = DPLL_J_TYPE,
638 .max_rate = 2000000000,
639 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
640 };
641
642 of_ti_dpll_setup(node, &dpll_ck_ops, &dd);
643 }
644 CLK_OF_DECLARE(ti_am3_jtype_dpll_clock, "ti,am3-dpll-j-type-clock",
645 of_ti_am3_jtype_dpll_setup);
646
of_ti_am3_no_gate_jtype_dpll_setup(struct device_node * node)647 static void __init of_ti_am3_no_gate_jtype_dpll_setup(struct device_node *node)
648 {
649 const struct dpll_data dd = {
650 .idlest_mask = 0x1,
651 .enable_mask = 0x7,
652 .mult_mask = 0x7ff << 8,
653 .div1_mask = 0x7f,
654 .max_multiplier = 2047,
655 .max_divider = 128,
656 .min_divider = 1,
657 .max_rate = 2000000000,
658 .flags = DPLL_J_TYPE,
659 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
660 };
661
662 of_ti_dpll_setup(node, &dpll_no_gate_ck_ops, &dd);
663 }
664 CLK_OF_DECLARE(ti_am3_no_gate_jtype_dpll_clock,
665 "ti,am3-dpll-no-gate-j-type-clock",
666 of_ti_am3_no_gate_jtype_dpll_setup);
667
of_ti_am3_dpll_setup(struct device_node * node)668 static void __init of_ti_am3_dpll_setup(struct device_node *node)
669 {
670 const struct dpll_data dd = {
671 .idlest_mask = 0x1,
672 .enable_mask = 0x7,
673 .ssc_enable_mask = 0x1 << 12,
674 .ssc_downspread_mask = 0x1 << 14,
675 .mult_mask = 0x7ff << 8,
676 .div1_mask = 0x7f,
677 .ssc_deltam_int_mask = 0x3 << 18,
678 .ssc_deltam_frac_mask = 0x3ffff,
679 .ssc_modfreq_mant_mask = 0x7f,
680 .ssc_modfreq_exp_mask = 0x7 << 8,
681 .max_multiplier = 2047,
682 .max_divider = 128,
683 .min_divider = 1,
684 .max_rate = 1000000000,
685 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
686 };
687
688 of_ti_dpll_setup(node, &dpll_ck_ops, &dd);
689 }
690 CLK_OF_DECLARE(ti_am3_dpll_clock, "ti,am3-dpll-clock", of_ti_am3_dpll_setup);
691
of_ti_am3_core_dpll_setup(struct device_node * node)692 static void __init of_ti_am3_core_dpll_setup(struct device_node *node)
693 {
694 const struct dpll_data dd = {
695 .idlest_mask = 0x1,
696 .enable_mask = 0x7,
697 .mult_mask = 0x7ff << 8,
698 .div1_mask = 0x7f,
699 .max_multiplier = 2047,
700 .max_divider = 128,
701 .min_divider = 1,
702 .max_rate = 1000000000,
703 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
704 };
705
706 of_ti_dpll_setup(node, &dpll_core_ck_ops, &dd);
707 }
708 CLK_OF_DECLARE(ti_am3_core_dpll_clock, "ti,am3-dpll-core-clock",
709 of_ti_am3_core_dpll_setup);
710
of_ti_omap2_core_dpll_setup(struct device_node * node)711 static void __init of_ti_omap2_core_dpll_setup(struct device_node *node)
712 {
713 const struct dpll_data dd = {
714 .enable_mask = 0x3,
715 .mult_mask = 0x3ff << 12,
716 .div1_mask = 0xf << 8,
717 .max_divider = 16,
718 .min_divider = 1,
719 };
720
721 of_ti_dpll_setup(node, &omap2_dpll_core_ck_ops, &dd);
722 }
723 CLK_OF_DECLARE(ti_omap2_core_dpll_clock, "ti,omap2-dpll-core-clock",
724 of_ti_omap2_core_dpll_setup);
725