Linux Audio

Check our new training course

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