blob: 47ebff772b13070f3d45dd381572fc61a6cce74a [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>
Tero Kristoed405a22015-01-29 22:24:28 +020024#include "clock.h"
Tero Kristof38b0dd2013-06-12 16:04:34 +030025
26#undef pr_fmt
27#define pr_fmt(fmt) "%s: " fmt, __func__
28
Tero Kristof38b0dd2013-06-12 16:04:34 +030029#if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \
30 defined(CONFIG_SOC_DRA7XX)
31static const struct clk_ops dpll_m4xen_ck_ops = {
32 .enable = &omap3_noncore_dpll_enable,
33 .disable = &omap3_noncore_dpll_disable,
34 .recalc_rate = &omap4_dpll_regm4xen_recalc,
35 .round_rate = &omap4_dpll_regm4xen_round_rate,
36 .set_rate = &omap3_noncore_dpll_set_rate,
Tero Kristo2e1a7b02014-10-03 16:57:14 +030037 .set_parent = &omap3_noncore_dpll_set_parent,
38 .set_rate_and_parent = &omap3_noncore_dpll_set_rate_and_parent,
39 .determine_rate = &omap4_dpll_regm4xen_determine_rate,
Tero Kristof38b0dd2013-06-12 16:04:34 +030040 .get_parent = &omap2_init_dpll_parent,
41};
Tero Kristoaa76fcf2014-02-21 17:36:21 +020042#else
43static const struct clk_ops dpll_m4xen_ck_ops = {};
Tero Kristof38b0dd2013-06-12 16:04:34 +030044#endif
45
Tero Kristoaa76fcf2014-02-21 17:36:21 +020046#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4) || \
47 defined(CONFIG_SOC_OMAP5) || defined(CONFIG_SOC_DRA7XX) || \
48 defined(CONFIG_SOC_AM33XX) || defined(CONFIG_SOC_AM43XX)
Tero Kristof38b0dd2013-06-12 16:04:34 +030049static const struct clk_ops dpll_core_ck_ops = {
50 .recalc_rate = &omap3_dpll_recalc,
51 .get_parent = &omap2_init_dpll_parent,
52};
53
Tero Kristof38b0dd2013-06-12 16:04:34 +030054static const struct clk_ops dpll_ck_ops = {
55 .enable = &omap3_noncore_dpll_enable,
56 .disable = &omap3_noncore_dpll_disable,
57 .recalc_rate = &omap3_dpll_recalc,
58 .round_rate = &omap2_dpll_round_rate,
59 .set_rate = &omap3_noncore_dpll_set_rate,
Tero Kristo2e1a7b02014-10-03 16:57:14 +030060 .set_parent = &omap3_noncore_dpll_set_parent,
61 .set_rate_and_parent = &omap3_noncore_dpll_set_rate_and_parent,
62 .determine_rate = &omap3_noncore_dpll_determine_rate,
Tero Kristof38b0dd2013-06-12 16:04:34 +030063 .get_parent = &omap2_init_dpll_parent,
64};
65
66static const struct clk_ops dpll_no_gate_ck_ops = {
67 .recalc_rate = &omap3_dpll_recalc,
68 .get_parent = &omap2_init_dpll_parent,
69 .round_rate = &omap2_dpll_round_rate,
70 .set_rate = &omap3_noncore_dpll_set_rate,
Tero Kristo2e1a7b02014-10-03 16:57:14 +030071 .set_parent = &omap3_noncore_dpll_set_parent,
72 .set_rate_and_parent = &omap3_noncore_dpll_set_rate_and_parent,
73 .determine_rate = &omap3_noncore_dpll_determine_rate,
Tero Kristof38b0dd2013-06-12 16:04:34 +030074};
Tero Kristoaa76fcf2014-02-21 17:36:21 +020075#else
76static const struct clk_ops dpll_core_ck_ops = {};
77static const struct clk_ops dpll_ck_ops = {};
78static const struct clk_ops dpll_no_gate_ck_ops = {};
79const struct clk_hw_omap_ops clkhwops_omap3_dpll = {};
80#endif
81
82#ifdef CONFIG_ARCH_OMAP2
83static const struct clk_ops omap2_dpll_core_ck_ops = {
84 .get_parent = &omap2_init_dpll_parent,
85 .recalc_rate = &omap2_dpllcore_recalc,
86 .round_rate = &omap2_dpll_round_rate,
87 .set_rate = &omap2_reprogram_dpllcore,
88};
89#else
90static const struct clk_ops omap2_dpll_core_ck_ops = {};
91#endif
92
93#ifdef CONFIG_ARCH_OMAP3
94static const struct clk_ops omap3_dpll_core_ck_ops = {
95 .get_parent = &omap2_init_dpll_parent,
96 .recalc_rate = &omap3_dpll_recalc,
97 .round_rate = &omap2_dpll_round_rate,
98};
99#else
100static const struct clk_ops omap3_dpll_core_ck_ops = {};
101#endif
Tero Kristof38b0dd2013-06-12 16:04:34 +0300102
103#ifdef CONFIG_ARCH_OMAP3
104static const struct clk_ops omap3_dpll_ck_ops = {
105 .enable = &omap3_noncore_dpll_enable,
106 .disable = &omap3_noncore_dpll_disable,
107 .get_parent = &omap2_init_dpll_parent,
108 .recalc_rate = &omap3_dpll_recalc,
109 .set_rate = &omap3_noncore_dpll_set_rate,
Tero Kristo2e1a7b02014-10-03 16:57:14 +0300110 .set_parent = &omap3_noncore_dpll_set_parent,
111 .set_rate_and_parent = &omap3_noncore_dpll_set_rate_and_parent,
112 .determine_rate = &omap3_noncore_dpll_determine_rate,
Tero Kristof38b0dd2013-06-12 16:04:34 +0300113 .round_rate = &omap2_dpll_round_rate,
114};
115
116static const struct clk_ops omap3_dpll_per_ck_ops = {
117 .enable = &omap3_noncore_dpll_enable,
118 .disable = &omap3_noncore_dpll_disable,
119 .get_parent = &omap2_init_dpll_parent,
120 .recalc_rate = &omap3_dpll_recalc,
121 .set_rate = &omap3_dpll4_set_rate,
Tero Kristo2e1a7b02014-10-03 16:57:14 +0300122 .set_parent = &omap3_noncore_dpll_set_parent,
123 .set_rate_and_parent = &omap3_dpll4_set_rate_and_parent,
124 .determine_rate = &omap3_noncore_dpll_determine_rate,
Tero Kristof38b0dd2013-06-12 16:04:34 +0300125 .round_rate = &omap2_dpll_round_rate,
126};
127#endif
128
129static const struct clk_ops dpll_x2_ck_ops = {
130 .recalc_rate = &omap3_clkoutx2_recalc,
131};
132
133/**
Tero Kristoed405a22015-01-29 22:24:28 +0200134 * _register_dpll - low level registration of a DPLL clock
Tero Kristof38b0dd2013-06-12 16:04:34 +0300135 * @hw: hardware clock definition for the clock
136 * @node: device node for the clock
137 *
138 * Finalizes DPLL registration process. In case a failure (clk-ref or
139 * clk-bypass is missing), the clock is added to retry list and
140 * the initialization is retried on later stage.
141 */
Tero Kristoed405a22015-01-29 22:24:28 +0200142static void __init _register_dpll(struct clk_hw *hw,
143 struct device_node *node)
Tero Kristof38b0dd2013-06-12 16:04:34 +0300144{
145 struct clk_hw_omap *clk_hw = to_clk_hw_omap(hw);
146 struct dpll_data *dd = clk_hw->dpll_data;
147 struct clk *clk;
148
149 dd->clk_ref = of_clk_get(node, 0);
150 dd->clk_bypass = of_clk_get(node, 1);
151
152 if (IS_ERR(dd->clk_ref) || IS_ERR(dd->clk_bypass)) {
153 pr_debug("clk-ref or clk-bypass missing for %s, retry later\n",
154 node->name);
Tero Kristoed405a22015-01-29 22:24:28 +0200155 if (!ti_clk_retry_init(node, hw, _register_dpll))
Tero Kristof38b0dd2013-06-12 16:04:34 +0300156 return;
157
158 goto cleanup;
159 }
160
161 /* register the clock */
162 clk = clk_register(NULL, &clk_hw->hw);
163
164 if (!IS_ERR(clk)) {
165 omap2_init_clk_hw_omap_clocks(clk);
166 of_clk_add_provider(node, of_clk_src_simple_get, clk);
167 kfree(clk_hw->hw.init->parent_names);
168 kfree(clk_hw->hw.init);
169 return;
170 }
171
172cleanup:
173 kfree(clk_hw->dpll_data);
174 kfree(clk_hw->hw.init->parent_names);
175 kfree(clk_hw->hw.init);
176 kfree(clk_hw);
177}
178
Tero Kristoed405a22015-01-29 22:24:28 +0200179void __iomem *_get_reg(u8 module, u16 offset)
180{
181 u32 reg;
182 struct clk_omap_reg *reg_setup;
183
184 reg_setup = (struct clk_omap_reg *)&reg;
185
186 reg_setup->index = module;
187 reg_setup->offset = offset;
188
189 return (void __iomem *)reg;
190}
191
192struct clk *ti_clk_register_dpll(struct ti_clk *setup)
193{
194 struct clk_hw_omap *clk_hw;
195 struct clk_init_data init = { NULL };
196 struct dpll_data *dd;
197 struct clk *clk;
198 struct ti_clk_dpll *dpll;
199 const struct clk_ops *ops = &omap3_dpll_ck_ops;
200 struct clk *clk_ref;
201 struct clk *clk_bypass;
202
203 dpll = setup->data;
204
205 if (dpll->num_parents < 2)
206 return ERR_PTR(-EINVAL);
207
208 clk_ref = clk_get_sys(NULL, dpll->parents[0]);
209 clk_bypass = clk_get_sys(NULL, dpll->parents[1]);
210
211 if (IS_ERR_OR_NULL(clk_ref) || IS_ERR_OR_NULL(clk_bypass))
212 return ERR_PTR(-EAGAIN);
213
214 dd = kzalloc(sizeof(*dd), GFP_KERNEL);
215 clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL);
216 if (!dd || !clk_hw) {
217 clk = ERR_PTR(-ENOMEM);
218 goto cleanup;
219 }
220
221 clk_hw->dpll_data = dd;
222 clk_hw->ops = &clkhwops_omap3_dpll;
223 clk_hw->hw.init = &init;
224 clk_hw->flags = MEMMAP_ADDRESSING;
225
226 init.name = setup->name;
227 init.ops = ops;
228
229 init.num_parents = dpll->num_parents;
230 init.parent_names = dpll->parents;
231
232 dd->control_reg = _get_reg(dpll->module, dpll->control_reg);
233 dd->idlest_reg = _get_reg(dpll->module, dpll->idlest_reg);
234 dd->mult_div1_reg = _get_reg(dpll->module, dpll->mult_div1_reg);
235 dd->autoidle_reg = _get_reg(dpll->module, dpll->autoidle_reg);
236
237 dd->modes = dpll->modes;
238 dd->div1_mask = dpll->div1_mask;
239 dd->idlest_mask = dpll->idlest_mask;
240 dd->mult_mask = dpll->mult_mask;
241 dd->autoidle_mask = dpll->autoidle_mask;
242 dd->enable_mask = dpll->enable_mask;
243 dd->sddiv_mask = dpll->sddiv_mask;
244 dd->dco_mask = dpll->dco_mask;
245 dd->max_divider = dpll->max_divider;
246 dd->min_divider = dpll->min_divider;
247 dd->max_multiplier = dpll->max_multiplier;
248 dd->auto_recal_bit = dpll->auto_recal_bit;
249 dd->recal_en_bit = dpll->recal_en_bit;
250 dd->recal_st_bit = dpll->recal_st_bit;
251
252 dd->clk_ref = clk_ref;
253 dd->clk_bypass = clk_bypass;
254
255 if (dpll->flags & CLKF_CORE)
256 ops = &omap3_dpll_core_ck_ops;
257
258 if (dpll->flags & CLKF_PER)
259 ops = &omap3_dpll_per_ck_ops;
260
261 if (dpll->flags & CLKF_J_TYPE)
262 dd->flags |= DPLL_J_TYPE;
263
264 clk = clk_register(NULL, &clk_hw->hw);
265
266 if (!IS_ERR(clk))
267 return clk;
268
269cleanup:
270 kfree(dd);
271 kfree(clk_hw);
272 return clk;
273}
274
Tero Kristof38b0dd2013-06-12 16:04:34 +0300275#if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \
Roger Quadros4332ec12014-06-17 17:03:24 +0300276 defined(CONFIG_SOC_DRA7XX) || defined(CONFIG_SOC_AM33XX) || \
277 defined(CONFIG_SOC_AM43XX)
Tero Kristof38b0dd2013-06-12 16:04:34 +0300278/**
Tero Kristoed405a22015-01-29 22:24:28 +0200279 * _register_dpll_x2 - Registers a DPLLx2 clock
Tero Kristof38b0dd2013-06-12 16:04:34 +0300280 * @node: device node for this clock
281 * @ops: clk_ops for this clock
282 * @hw_ops: clk_hw_ops for this clock
283 *
284 * Initializes a DPLL x 2 clock from device tree data.
285 */
Tero Kristoed405a22015-01-29 22:24:28 +0200286static void _register_dpll_x2(struct device_node *node,
287 const struct clk_ops *ops,
288 const struct clk_hw_omap_ops *hw_ops)
Tero Kristof38b0dd2013-06-12 16:04:34 +0300289{
290 struct clk *clk;
291 struct clk_init_data init = { NULL };
292 struct clk_hw_omap *clk_hw;
293 const char *name = node->name;
294 const char *parent_name;
295
296 parent_name = of_clk_get_parent_name(node, 0);
297 if (!parent_name) {
298 pr_err("%s must have parent\n", node->name);
299 return;
300 }
301
302 clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL);
303 if (!clk_hw)
304 return;
305
306 clk_hw->ops = hw_ops;
307 clk_hw->hw.init = &init;
308
309 init.name = name;
310 init.ops = ops;
311 init.parent_names = &parent_name;
312 init.num_parents = 1;
313
314 /* register the clock */
315 clk = clk_register(NULL, &clk_hw->hw);
316
317 if (IS_ERR(clk)) {
318 kfree(clk_hw);
319 } else {
320 omap2_init_clk_hw_omap_clocks(clk);
321 of_clk_add_provider(node, of_clk_src_simple_get, clk);
322 }
323}
324#endif
325
326/**
327 * of_ti_dpll_setup - Setup function for OMAP DPLL clocks
328 * @node: device node containing the DPLL info
329 * @ops: ops for the DPLL
330 * @ddt: DPLL data template to use
Tero Kristof38b0dd2013-06-12 16:04:34 +0300331 *
332 * Initializes a DPLL clock from device tree data.
333 */
334static void __init of_ti_dpll_setup(struct device_node *node,
335 const struct clk_ops *ops,
Tero Kristoa6fe3772014-02-21 17:22:32 +0200336 const struct dpll_data *ddt)
Tero Kristof38b0dd2013-06-12 16:04:34 +0300337{
338 struct clk_hw_omap *clk_hw = NULL;
339 struct clk_init_data *init = NULL;
340 const char **parent_names = NULL;
341 struct dpll_data *dd = NULL;
342 int i;
343 u8 dpll_mode = 0;
344
345 dd = kzalloc(sizeof(*dd), GFP_KERNEL);
346 clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL);
347 init = kzalloc(sizeof(*init), GFP_KERNEL);
348 if (!dd || !clk_hw || !init)
349 goto cleanup;
350
351 memcpy(dd, ddt, sizeof(*dd));
352
353 clk_hw->dpll_data = dd;
354 clk_hw->ops = &clkhwops_omap3_dpll;
355 clk_hw->hw.init = init;
356 clk_hw->flags = MEMMAP_ADDRESSING;
357
358 init->name = node->name;
359 init->ops = ops;
360
361 init->num_parents = of_clk_get_parent_count(node);
362 if (init->num_parents < 1) {
363 pr_err("%s must have parent(s)\n", node->name);
364 goto cleanup;
365 }
366
367 parent_names = kzalloc(sizeof(char *) * init->num_parents, GFP_KERNEL);
368 if (!parent_names)
369 goto cleanup;
370
371 for (i = 0; i < init->num_parents; i++)
372 parent_names[i] = of_clk_get_parent_name(node, i);
373
374 init->parent_names = parent_names;
375
376 dd->control_reg = ti_clk_get_reg_addr(node, 0);
Tero Kristof38b0dd2013-06-12 16:04:34 +0300377
Tero Kristoaa76fcf2014-02-21 17:36:21 +0200378 /*
379 * Special case for OMAP2 DPLL, register order is different due to
380 * missing idlest_reg, also clkhwops is different. Detected from
381 * missing idlest_mask.
382 */
383 if (!dd->idlest_mask) {
384 dd->mult_div1_reg = ti_clk_get_reg_addr(node, 1);
385#ifdef CONFIG_ARCH_OMAP2
386 clk_hw->ops = &clkhwops_omap2xxx_dpll;
387 omap2xxx_clkt_dpllcore_init(&clk_hw->hw);
388#endif
389 } else {
390 dd->idlest_reg = ti_clk_get_reg_addr(node, 1);
391 if (!dd->idlest_reg)
392 goto cleanup;
393
394 dd->mult_div1_reg = ti_clk_get_reg_addr(node, 2);
395 }
396
397 if (!dd->control_reg || !dd->mult_div1_reg)
Tero Kristof38b0dd2013-06-12 16:04:34 +0300398 goto cleanup;
399
Tero Kristoa6fe3772014-02-21 17:22:32 +0200400 if (dd->autoidle_mask) {
Tero Kristof38b0dd2013-06-12 16:04:34 +0300401 dd->autoidle_reg = ti_clk_get_reg_addr(node, 3);
402 if (!dd->autoidle_reg)
403 goto cleanup;
404 }
405
406 if (of_property_read_bool(node, "ti,low-power-stop"))
407 dpll_mode |= 1 << DPLL_LOW_POWER_STOP;
408
409 if (of_property_read_bool(node, "ti,low-power-bypass"))
410 dpll_mode |= 1 << DPLL_LOW_POWER_BYPASS;
411
412 if (of_property_read_bool(node, "ti,lock"))
413 dpll_mode |= 1 << DPLL_LOCKED;
414
415 if (dpll_mode)
416 dd->modes = dpll_mode;
417
Tero Kristoed405a22015-01-29 22:24:28 +0200418 _register_dpll(&clk_hw->hw, node);
Tero Kristof38b0dd2013-06-12 16:04:34 +0300419 return;
420
421cleanup:
422 kfree(dd);
423 kfree(parent_names);
424 kfree(init);
425 kfree(clk_hw);
426}
427
428#if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \
429 defined(CONFIG_SOC_DRA7XX)
430static void __init of_ti_omap4_dpll_x2_setup(struct device_node *node)
431{
Tero Kristoed405a22015-01-29 22:24:28 +0200432 _register_dpll_x2(node, &dpll_x2_ck_ops, &clkhwops_omap4_dpllmx);
Tero Kristof38b0dd2013-06-12 16:04:34 +0300433}
434CLK_OF_DECLARE(ti_omap4_dpll_x2_clock, "ti,omap4-dpll-x2-clock",
435 of_ti_omap4_dpll_x2_setup);
436#endif
437
Roger Quadros4332ec12014-06-17 17:03:24 +0300438#if defined(CONFIG_SOC_AM33XX) || defined(CONFIG_SOC_AM43XX)
Tero Kristof38b0dd2013-06-12 16:04:34 +0300439static void __init of_ti_am3_dpll_x2_setup(struct device_node *node)
440{
Tero Kristoed405a22015-01-29 22:24:28 +0200441 _register_dpll_x2(node, &dpll_x2_ck_ops, NULL);
Tero Kristof38b0dd2013-06-12 16:04:34 +0300442}
443CLK_OF_DECLARE(ti_am3_dpll_x2_clock, "ti,am3-dpll-x2-clock",
444 of_ti_am3_dpll_x2_setup);
445#endif
446
447#ifdef CONFIG_ARCH_OMAP3
448static void __init of_ti_omap3_dpll_setup(struct device_node *node)
449{
450 const struct dpll_data dd = {
451 .idlest_mask = 0x1,
452 .enable_mask = 0x7,
453 .autoidle_mask = 0x7,
454 .mult_mask = 0x7ff << 8,
455 .div1_mask = 0x7f,
456 .max_multiplier = 2047,
457 .max_divider = 128,
458 .min_divider = 1,
459 .freqsel_mask = 0xf0,
460 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
461 };
462
Tero Kristoa6fe3772014-02-21 17:22:32 +0200463 of_ti_dpll_setup(node, &omap3_dpll_ck_ops, &dd);
Tero Kristof38b0dd2013-06-12 16:04:34 +0300464}
465CLK_OF_DECLARE(ti_omap3_dpll_clock, "ti,omap3-dpll-clock",
466 of_ti_omap3_dpll_setup);
467
468static void __init of_ti_omap3_core_dpll_setup(struct device_node *node)
469{
470 const struct dpll_data dd = {
471 .idlest_mask = 0x1,
472 .enable_mask = 0x7,
473 .autoidle_mask = 0x7,
474 .mult_mask = 0x7ff << 16,
475 .div1_mask = 0x7f << 8,
476 .max_multiplier = 2047,
477 .max_divider = 128,
478 .min_divider = 1,
479 .freqsel_mask = 0xf0,
480 };
481
Tero Kristoa6fe3772014-02-21 17:22:32 +0200482 of_ti_dpll_setup(node, &omap3_dpll_core_ck_ops, &dd);
Tero Kristof38b0dd2013-06-12 16:04:34 +0300483}
484CLK_OF_DECLARE(ti_omap3_core_dpll_clock, "ti,omap3-dpll-core-clock",
485 of_ti_omap3_core_dpll_setup);
486
487static void __init of_ti_omap3_per_dpll_setup(struct device_node *node)
488{
489 const struct dpll_data dd = {
490 .idlest_mask = 0x1 << 1,
491 .enable_mask = 0x7 << 16,
492 .autoidle_mask = 0x7 << 3,
493 .mult_mask = 0x7ff << 8,
494 .div1_mask = 0x7f,
495 .max_multiplier = 2047,
496 .max_divider = 128,
497 .min_divider = 1,
498 .freqsel_mask = 0xf00000,
499 .modes = (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED),
500 };
501
Tero Kristoa6fe3772014-02-21 17:22:32 +0200502 of_ti_dpll_setup(node, &omap3_dpll_per_ck_ops, &dd);
Tero Kristof38b0dd2013-06-12 16:04:34 +0300503}
504CLK_OF_DECLARE(ti_omap3_per_dpll_clock, "ti,omap3-dpll-per-clock",
505 of_ti_omap3_per_dpll_setup);
506
507static void __init of_ti_omap3_per_jtype_dpll_setup(struct device_node *node)
508{
509 const struct dpll_data dd = {
510 .idlest_mask = 0x1 << 1,
511 .enable_mask = 0x7 << 16,
512 .autoidle_mask = 0x7 << 3,
513 .mult_mask = 0xfff << 8,
514 .div1_mask = 0x7f,
515 .max_multiplier = 4095,
516 .max_divider = 128,
517 .min_divider = 1,
518 .sddiv_mask = 0xff << 24,
519 .dco_mask = 0xe << 20,
520 .flags = DPLL_J_TYPE,
521 .modes = (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED),
522 };
523
Tero Kristoa6fe3772014-02-21 17:22:32 +0200524 of_ti_dpll_setup(node, &omap3_dpll_per_ck_ops, &dd);
Tero Kristof38b0dd2013-06-12 16:04:34 +0300525}
526CLK_OF_DECLARE(ti_omap3_per_jtype_dpll_clock, "ti,omap3-dpll-per-j-type-clock",
527 of_ti_omap3_per_jtype_dpll_setup);
528#endif
529
530static void __init of_ti_omap4_dpll_setup(struct device_node *node)
531{
532 const struct dpll_data dd = {
533 .idlest_mask = 0x1,
534 .enable_mask = 0x7,
535 .autoidle_mask = 0x7,
536 .mult_mask = 0x7ff << 8,
537 .div1_mask = 0x7f,
538 .max_multiplier = 2047,
539 .max_divider = 128,
540 .min_divider = 1,
541 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
542 };
543
Tero Kristoa6fe3772014-02-21 17:22:32 +0200544 of_ti_dpll_setup(node, &dpll_ck_ops, &dd);
Tero Kristof38b0dd2013-06-12 16:04:34 +0300545}
546CLK_OF_DECLARE(ti_omap4_dpll_clock, "ti,omap4-dpll-clock",
547 of_ti_omap4_dpll_setup);
548
Nishanth Menonb4be0182014-05-16 05:45:59 -0500549static void __init of_ti_omap5_mpu_dpll_setup(struct device_node *node)
550{
551 const struct dpll_data dd = {
552 .idlest_mask = 0x1,
553 .enable_mask = 0x7,
554 .autoidle_mask = 0x7,
555 .mult_mask = 0x7ff << 8,
556 .div1_mask = 0x7f,
557 .max_multiplier = 2047,
558 .max_divider = 128,
559 .dcc_mask = BIT(22),
560 .dcc_rate = 1400000000, /* DCC beyond 1.4GHz */
561 .min_divider = 1,
562 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
563 };
564
565 of_ti_dpll_setup(node, &dpll_ck_ops, &dd);
566}
567CLK_OF_DECLARE(of_ti_omap5_mpu_dpll_clock, "ti,omap5-mpu-dpll-clock",
568 of_ti_omap5_mpu_dpll_setup);
569
Tero Kristof38b0dd2013-06-12 16:04:34 +0300570static void __init of_ti_omap4_core_dpll_setup(struct device_node *node)
571{
572 const struct dpll_data dd = {
573 .idlest_mask = 0x1,
574 .enable_mask = 0x7,
575 .autoidle_mask = 0x7,
576 .mult_mask = 0x7ff << 8,
577 .div1_mask = 0x7f,
578 .max_multiplier = 2047,
579 .max_divider = 128,
580 .min_divider = 1,
581 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
582 };
583
Tero Kristoa6fe3772014-02-21 17:22:32 +0200584 of_ti_dpll_setup(node, &dpll_core_ck_ops, &dd);
Tero Kristof38b0dd2013-06-12 16:04:34 +0300585}
586CLK_OF_DECLARE(ti_omap4_core_dpll_clock, "ti,omap4-dpll-core-clock",
587 of_ti_omap4_core_dpll_setup);
588
589#if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \
590 defined(CONFIG_SOC_DRA7XX)
591static void __init of_ti_omap4_m4xen_dpll_setup(struct device_node *node)
592{
593 const struct dpll_data dd = {
594 .idlest_mask = 0x1,
595 .enable_mask = 0x7,
596 .autoidle_mask = 0x7,
597 .mult_mask = 0x7ff << 8,
598 .div1_mask = 0x7f,
599 .max_multiplier = 2047,
600 .max_divider = 128,
601 .min_divider = 1,
602 .m4xen_mask = 0x800,
603 .lpmode_mask = 1 << 10,
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_m4xen_ck_ops, &dd);
Tero Kristof38b0dd2013-06-12 16:04:34 +0300608}
609CLK_OF_DECLARE(ti_omap4_m4xen_dpll_clock, "ti,omap4-dpll-m4xen-clock",
610 of_ti_omap4_m4xen_dpll_setup);
611
612static void __init of_ti_omap4_jtype_dpll_setup(struct device_node *node)
613{
614 const struct dpll_data dd = {
615 .idlest_mask = 0x1,
616 .enable_mask = 0x7,
617 .autoidle_mask = 0x7,
618 .mult_mask = 0xfff << 8,
619 .div1_mask = 0xff,
620 .max_multiplier = 4095,
621 .max_divider = 256,
622 .min_divider = 1,
623 .sddiv_mask = 0xff << 24,
624 .flags = DPLL_J_TYPE,
625 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
626 };
627
Tero Kristoa6fe3772014-02-21 17:22:32 +0200628 of_ti_dpll_setup(node, &dpll_m4xen_ck_ops, &dd);
Tero Kristof38b0dd2013-06-12 16:04:34 +0300629}
630CLK_OF_DECLARE(ti_omap4_jtype_dpll_clock, "ti,omap4-dpll-j-type-clock",
631 of_ti_omap4_jtype_dpll_setup);
632#endif
633
634static void __init of_ti_am3_no_gate_dpll_setup(struct device_node *node)
635{
636 const struct dpll_data dd = {
637 .idlest_mask = 0x1,
638 .enable_mask = 0x7,
Tero Kristof38b0dd2013-06-12 16:04:34 +0300639 .mult_mask = 0x7ff << 8,
640 .div1_mask = 0x7f,
641 .max_multiplier = 2047,
642 .max_divider = 128,
643 .min_divider = 1,
644 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
645 };
646
Tero Kristoa6fe3772014-02-21 17:22:32 +0200647 of_ti_dpll_setup(node, &dpll_no_gate_ck_ops, &dd);
Tero Kristof38b0dd2013-06-12 16:04:34 +0300648}
649CLK_OF_DECLARE(ti_am3_no_gate_dpll_clock, "ti,am3-dpll-no-gate-clock",
650 of_ti_am3_no_gate_dpll_setup);
651
652static void __init of_ti_am3_jtype_dpll_setup(struct device_node *node)
653{
654 const struct dpll_data dd = {
655 .idlest_mask = 0x1,
656 .enable_mask = 0x7,
Tero Kristof38b0dd2013-06-12 16:04:34 +0300657 .mult_mask = 0x7ff << 8,
658 .div1_mask = 0x7f,
659 .max_multiplier = 4095,
660 .max_divider = 256,
661 .min_divider = 2,
662 .flags = DPLL_J_TYPE,
663 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
664 };
665
Tero Kristoa6fe3772014-02-21 17:22:32 +0200666 of_ti_dpll_setup(node, &dpll_ck_ops, &dd);
Tero Kristof38b0dd2013-06-12 16:04:34 +0300667}
668CLK_OF_DECLARE(ti_am3_jtype_dpll_clock, "ti,am3-dpll-j-type-clock",
669 of_ti_am3_jtype_dpll_setup);
670
671static void __init of_ti_am3_no_gate_jtype_dpll_setup(struct device_node *node)
672{
673 const struct dpll_data dd = {
674 .idlest_mask = 0x1,
675 .enable_mask = 0x7,
Tero Kristof38b0dd2013-06-12 16:04:34 +0300676 .mult_mask = 0x7ff << 8,
677 .div1_mask = 0x7f,
678 .max_multiplier = 2047,
679 .max_divider = 128,
680 .min_divider = 1,
681 .flags = DPLL_J_TYPE,
682 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
683 };
684
Tero Kristoa6fe3772014-02-21 17:22:32 +0200685 of_ti_dpll_setup(node, &dpll_no_gate_ck_ops, &dd);
Tero Kristof38b0dd2013-06-12 16:04:34 +0300686}
687CLK_OF_DECLARE(ti_am3_no_gate_jtype_dpll_clock,
688 "ti,am3-dpll-no-gate-j-type-clock",
689 of_ti_am3_no_gate_jtype_dpll_setup);
690
691static void __init of_ti_am3_dpll_setup(struct device_node *node)
692{
693 const struct dpll_data dd = {
694 .idlest_mask = 0x1,
695 .enable_mask = 0x7,
Tero Kristof38b0dd2013-06-12 16:04:34 +0300696 .mult_mask = 0x7ff << 8,
697 .div1_mask = 0x7f,
698 .max_multiplier = 2047,
699 .max_divider = 128,
700 .min_divider = 1,
701 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
702 };
703
Tero Kristoa6fe3772014-02-21 17:22:32 +0200704 of_ti_dpll_setup(node, &dpll_ck_ops, &dd);
Tero Kristof38b0dd2013-06-12 16:04:34 +0300705}
706CLK_OF_DECLARE(ti_am3_dpll_clock, "ti,am3-dpll-clock", of_ti_am3_dpll_setup);
707
708static void __init of_ti_am3_core_dpll_setup(struct device_node *node)
709{
710 const struct dpll_data dd = {
711 .idlest_mask = 0x1,
712 .enable_mask = 0x7,
Tero Kristof38b0dd2013-06-12 16:04:34 +0300713 .mult_mask = 0x7ff << 8,
714 .div1_mask = 0x7f,
715 .max_multiplier = 2047,
716 .max_divider = 128,
717 .min_divider = 1,
718 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
719 };
720
Tero Kristoa6fe3772014-02-21 17:22:32 +0200721 of_ti_dpll_setup(node, &dpll_core_ck_ops, &dd);
Tero Kristof38b0dd2013-06-12 16:04:34 +0300722}
723CLK_OF_DECLARE(ti_am3_core_dpll_clock, "ti,am3-dpll-core-clock",
724 of_ti_am3_core_dpll_setup);
Tero Kristoaa76fcf2014-02-21 17:36:21 +0200725
726static void __init of_ti_omap2_core_dpll_setup(struct device_node *node)
727{
728 const struct dpll_data dd = {
729 .enable_mask = 0x3,
730 .mult_mask = 0x3ff << 12,
731 .div1_mask = 0xf << 8,
732 .max_divider = 16,
733 .min_divider = 1,
734 };
735
736 of_ti_dpll_setup(node, &omap2_dpll_core_ck_ops, &dd);
737}
738CLK_OF_DECLARE(ti_omap2_core_dpll_clock, "ti,omap2-dpll-core-clock",
739 of_ti_omap2_core_dpll_setup);