1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * clk-xgene.c - AppliedMicro X-Gene Clock Interface
4 *
5 * Copyright (c) 2013, Applied Micro Circuits Corporation
6 * Author: Loc Ho <lho@apm.com>
7 */
8#include <linux/module.h>
9#include <linux/spinlock.h>
10#include <linux/io.h>
11#include <linux/of.h>
12#include <linux/clkdev.h>
13#include <linux/clk-provider.h>
14#include <linux/of_address.h>
15
16/* Register SCU_PCPPLL bit fields */
17#define N_DIV_RD(src)			((src) & 0x000001ff)
18#define SC_N_DIV_RD(src)		((src) & 0x0000007f)
19#define SC_OUTDIV2(src)			(((src) & 0x00000100) >> 8)
20
21/* Register SCU_SOCPLL bit fields */
22#define CLKR_RD(src)			(((src) & 0x07000000)>>24)
23#define CLKOD_RD(src)			(((src) & 0x00300000)>>20)
24#define REGSPEC_RESET_F1_MASK		0x00010000
25#define CLKF_RD(src)			(((src) & 0x000001ff))
26
27#define XGENE_CLK_DRIVER_VER		"0.1"
28
29static DEFINE_SPINLOCK(clk_lock);
30
31static inline u32 xgene_clk_read(void __iomem *csr)
32{
33	return readl_relaxed(csr);
34}
35
36static inline void xgene_clk_write(u32 data, void __iomem *csr)
37{
38	writel_relaxed(data, csr);
39}
40
41/* PLL Clock */
42enum xgene_pll_type {
43	PLL_TYPE_PCP = 0,
44	PLL_TYPE_SOC = 1,
45};
46
47struct xgene_clk_pll {
48	struct clk_hw	hw;
49	void __iomem	*reg;
50	spinlock_t	*lock;
51	u32		pll_offset;
52	enum xgene_pll_type	type;
53	int		version;
54};
55
56#define to_xgene_clk_pll(_hw) container_of(_hw, struct xgene_clk_pll, hw)
57
58static int xgene_clk_pll_is_enabled(struct clk_hw *hw)
59{
60	struct xgene_clk_pll *pllclk = to_xgene_clk_pll(hw);
61	u32 data;
62
63	data = xgene_clk_read(pllclk->reg + pllclk->pll_offset);
64	pr_debug("%s pll %s\n", clk_hw_get_name(hw),
65		data & REGSPEC_RESET_F1_MASK ? "disabled" : "enabled");
66
67	return data & REGSPEC_RESET_F1_MASK ? 0 : 1;
68}
69
70static unsigned long xgene_clk_pll_recalc_rate(struct clk_hw *hw,
71				unsigned long parent_rate)
72{
73	struct xgene_clk_pll *pllclk = to_xgene_clk_pll(hw);
74	unsigned long fref;
75	unsigned long fvco;
76	u32 pll;
77	u32 nref;
78	u32 nout;
79	u32 nfb;
80
81	pll = xgene_clk_read(pllclk->reg + pllclk->pll_offset);
82
83	if (pllclk->version <= 1) {
84		if (pllclk->type == PLL_TYPE_PCP) {
85			/*
86			* PLL VCO = Reference clock * NF
87			* PCP PLL = PLL_VCO / 2
88			*/
89			nout = 2;
90			fvco = parent_rate * (N_DIV_RD(pll) + 4);
91		} else {
92			/*
93			* Fref = Reference Clock / NREF;
94			* Fvco = Fref * NFB;
95			* Fout = Fvco / NOUT;
96			*/
97			nref = CLKR_RD(pll) + 1;
98			nout = CLKOD_RD(pll) + 1;
99			nfb = CLKF_RD(pll);
100			fref = parent_rate / nref;
101			fvco = fref * nfb;
102		}
103	} else {
104		/*
105		 * fvco = Reference clock * FBDIVC
106		 * PLL freq = fvco / NOUT
107		 */
108		nout = SC_OUTDIV2(pll) ? 2 : 3;
109		fvco = parent_rate * SC_N_DIV_RD(pll);
110	}
111	pr_debug("%s pll recalc rate %ld parent %ld version %d\n",
112		 clk_hw_get_name(hw), fvco / nout, parent_rate,
113		 pllclk->version);
114
115	return fvco / nout;
116}
117
118static const struct clk_ops xgene_clk_pll_ops = {
119	.is_enabled = xgene_clk_pll_is_enabled,
120	.recalc_rate = xgene_clk_pll_recalc_rate,
121};
122
123static struct clk *xgene_register_clk_pll(struct device *dev,
124	const char *name, const char *parent_name,
125	unsigned long flags, void __iomem *reg, u32 pll_offset,
126	u32 type, spinlock_t *lock, int version)
127{
128	struct xgene_clk_pll *apmclk;
129	struct clk *clk;
130	struct clk_init_data init;
131
132	/* allocate the APM clock structure */
133	apmclk = kzalloc(sizeof(*apmclk), GFP_KERNEL);
134	if (!apmclk)
135		return ERR_PTR(-ENOMEM);
136
137	init.name = name;
138	init.ops = &xgene_clk_pll_ops;
139	init.flags = flags;
140	init.parent_names = parent_name ? &parent_name : NULL;
141	init.num_parents = parent_name ? 1 : 0;
142
143	apmclk->version = version;
144	apmclk->reg = reg;
145	apmclk->lock = lock;
146	apmclk->pll_offset = pll_offset;
147	apmclk->type = type;
148	apmclk->hw.init = &init;
149
150	/* Register the clock */
151	clk = clk_register(dev, &apmclk->hw);
152	if (IS_ERR(clk)) {
153		pr_err("%s: could not register clk %s\n", __func__, name);
154		kfree(apmclk);
155		return NULL;
156	}
157	return clk;
158}
159
160static int xgene_pllclk_version(struct device_node *np)
161{
162	if (of_device_is_compatible(np, "apm,xgene-socpll-clock"))
163		return 1;
164	if (of_device_is_compatible(np, "apm,xgene-pcppll-clock"))
165		return 1;
166	return 2;
167}
168
169static void xgene_pllclk_init(struct device_node *np, enum xgene_pll_type pll_type)
170{
171	const char *clk_name = np->full_name;
172	struct clk *clk;
173	void __iomem *reg;
174	int version = xgene_pllclk_version(np);
175
176	reg = of_iomap(np, 0);
177	if (!reg) {
178		pr_err("Unable to map CSR register for %pOF\n", np);
179		return;
180	}
181	of_property_read_string(np, "clock-output-names", &clk_name);
182	clk = xgene_register_clk_pll(NULL,
183			clk_name, of_clk_get_parent_name(np, 0),
184			0, reg, 0, pll_type, &clk_lock,
185			version);
186	if (!IS_ERR(clk)) {
187		of_clk_add_provider(np, of_clk_src_simple_get, clk);
188		clk_register_clkdev(clk, clk_name, NULL);
189		pr_debug("Add %s clock PLL\n", clk_name);
190	}
191}
192
193static void xgene_socpllclk_init(struct device_node *np)
194{
195	xgene_pllclk_init(np, PLL_TYPE_SOC);
196}
197
198static void xgene_pcppllclk_init(struct device_node *np)
199{
200	xgene_pllclk_init(np, PLL_TYPE_PCP);
201}
202
203/**
204 * struct xgene_clk_pmd - PMD clock
205 *
206 * @hw:		handle between common and hardware-specific interfaces
207 * @reg:	register containing the fractional scale multiplier (scaler)
208 * @shift:	shift to the unit bit field
209 * @denom:	1/denominator unit
210 * @lock:	register lock
211 * Flags:
212 * XGENE_CLK_PMD_SCALE_INVERTED - By default the scaler is the value read
213 *	from the register plus one. For example,
214 *		0 for (0 + 1) / denom,
215 *		1 for (1 + 1) / denom and etc.
216 *	If this flag is set, it is
217 *		0 for (denom - 0) / denom,
218 *		1 for (denom - 1) / denom and etc.
219 *
220 */
221struct xgene_clk_pmd {
222	struct clk_hw	hw;
223	void __iomem	*reg;
224	u8		shift;
225	u32		mask;
226	u64		denom;
227	u32		flags;
228	spinlock_t	*lock;
229};
230
231#define to_xgene_clk_pmd(_hw) container_of(_hw, struct xgene_clk_pmd, hw)
232
233#define XGENE_CLK_PMD_SCALE_INVERTED	BIT(0)
234#define XGENE_CLK_PMD_SHIFT		8
235#define XGENE_CLK_PMD_WIDTH		3
236
237static unsigned long xgene_clk_pmd_recalc_rate(struct clk_hw *hw,
238					       unsigned long parent_rate)
239{
240	struct xgene_clk_pmd *fd = to_xgene_clk_pmd(hw);
241	unsigned long flags = 0;
242	u64 ret, scale;
243	u32 val;
244
245	if (fd->lock)
246		spin_lock_irqsave(fd->lock, flags);
247	else
248		__acquire(fd->lock);
249
250	val = readl(fd->reg);
251
252	if (fd->lock)
253		spin_unlock_irqrestore(fd->lock, flags);
254	else
255		__release(fd->lock);
256
257	ret = (u64)parent_rate;
258
259	scale = (val & fd->mask) >> fd->shift;
260	if (fd->flags & XGENE_CLK_PMD_SCALE_INVERTED)
261		scale = fd->denom - scale;
262	else
263		scale++;
264
265	/* freq = parent_rate * scaler / denom */
266	do_div(ret, fd->denom);
267	ret *= scale;
268	if (ret == 0)
269		ret = (u64)parent_rate;
270
271	return ret;
272}
273
274static long xgene_clk_pmd_round_rate(struct clk_hw *hw, unsigned long rate,
275				     unsigned long *parent_rate)
276{
277	struct xgene_clk_pmd *fd = to_xgene_clk_pmd(hw);
278	u64 ret, scale;
279
280	if (!rate || rate >= *parent_rate)
281		return *parent_rate;
282
283	/* freq = parent_rate * scaler / denom */
284	ret = rate * fd->denom;
285	scale = DIV_ROUND_UP_ULL(ret, *parent_rate);
286
287	ret = (u64)*parent_rate * scale;
288	do_div(ret, fd->denom);
289
290	return ret;
291}
292
293static int xgene_clk_pmd_set_rate(struct clk_hw *hw, unsigned long rate,
294				  unsigned long parent_rate)
295{
296	struct xgene_clk_pmd *fd = to_xgene_clk_pmd(hw);
297	unsigned long flags = 0;
298	u64 scale, ret;
299	u32 val;
300
301	/*
302	 * Compute the scaler:
303	 *
304	 * freq = parent_rate * scaler / denom, or
305	 * scaler = freq * denom / parent_rate
306	 */
307	ret = rate * fd->denom;
308	scale = DIV_ROUND_UP_ULL(ret, (u64)parent_rate);
309
310	/* Check if inverted */
311	if (fd->flags & XGENE_CLK_PMD_SCALE_INVERTED)
312		scale = fd->denom - scale;
313	else
314		scale--;
315
316	if (fd->lock)
317		spin_lock_irqsave(fd->lock, flags);
318	else
319		__acquire(fd->lock);
320
321	val = readl(fd->reg);
322	val &= ~fd->mask;
323	val |= (scale << fd->shift);
324	writel(val, fd->reg);
325
326	if (fd->lock)
327		spin_unlock_irqrestore(fd->lock, flags);
328	else
329		__release(fd->lock);
330
331	return 0;
332}
333
334static const struct clk_ops xgene_clk_pmd_ops = {
335	.recalc_rate = xgene_clk_pmd_recalc_rate,
336	.round_rate = xgene_clk_pmd_round_rate,
337	.set_rate = xgene_clk_pmd_set_rate,
338};
339
340static struct clk *
341xgene_register_clk_pmd(struct device *dev,
342		       const char *name, const char *parent_name,
343		       unsigned long flags, void __iomem *reg, u8 shift,
344		       u8 width, u64 denom, u32 clk_flags, spinlock_t *lock)
345{
346	struct xgene_clk_pmd *fd;
347	struct clk_init_data init;
348	struct clk *clk;
349
350	fd = kzalloc(sizeof(*fd), GFP_KERNEL);
351	if (!fd)
352		return ERR_PTR(-ENOMEM);
353
354	init.name = name;
355	init.ops = &xgene_clk_pmd_ops;
356	init.flags = flags;
357	init.parent_names = parent_name ? &parent_name : NULL;
358	init.num_parents = parent_name ? 1 : 0;
359
360	fd->reg = reg;
361	fd->shift = shift;
362	fd->mask = (BIT(width) - 1) << shift;
363	fd->denom = denom;
364	fd->flags = clk_flags;
365	fd->lock = lock;
366	fd->hw.init = &init;
367
368	clk = clk_register(dev, &fd->hw);
369	if (IS_ERR(clk)) {
370		pr_err("%s: could not register clk %s\n", __func__, name);
371		kfree(fd);
372		return NULL;
373	}
374
375	return clk;
376}
377
378static void xgene_pmdclk_init(struct device_node *np)
379{
380	const char *clk_name = np->full_name;
381	void __iomem *csr_reg;
382	struct resource res;
383	struct clk *clk;
384	u64 denom;
385	u32 flags = 0;
386	int rc;
387
388	/* Check if the entry is disabled */
389	if (!of_device_is_available(np))
390		return;
391
392	/* Parse the DTS register for resource */
393	rc = of_address_to_resource(np, 0, &res);
394	if (rc != 0) {
395		pr_err("no DTS register for %pOF\n", np);
396		return;
397	}
398	csr_reg = of_iomap(np, 0);
399	if (!csr_reg) {
400		pr_err("Unable to map resource for %pOF\n", np);
401		return;
402	}
403	of_property_read_string(np, "clock-output-names", &clk_name);
404
405	denom = BIT(XGENE_CLK_PMD_WIDTH);
406	flags |= XGENE_CLK_PMD_SCALE_INVERTED;
407
408	clk = xgene_register_clk_pmd(NULL, clk_name,
409				     of_clk_get_parent_name(np, 0), 0,
410				     csr_reg, XGENE_CLK_PMD_SHIFT,
411				     XGENE_CLK_PMD_WIDTH, denom,
412				     flags, &clk_lock);
413	if (!IS_ERR(clk)) {
414		of_clk_add_provider(np, of_clk_src_simple_get, clk);
415		clk_register_clkdev(clk, clk_name, NULL);
416		pr_debug("Add %s clock\n", clk_name);
417	} else {
418		if (csr_reg)
419			iounmap(csr_reg);
420	}
421}
422
423/* IP Clock */
424struct xgene_dev_parameters {
425	void __iomem *csr_reg;		/* CSR for IP clock */
426	u32 reg_clk_offset;		/* Offset to clock enable CSR */
427	u32 reg_clk_mask;		/* Mask bit for clock enable */
428	u32 reg_csr_offset;		/* Offset to CSR reset */
429	u32 reg_csr_mask;		/* Mask bit for disable CSR reset */
430	void __iomem *divider_reg;	/* CSR for divider */
431	u32 reg_divider_offset;		/* Offset to divider register */
432	u32 reg_divider_shift;		/* Bit shift to divider field */
433	u32 reg_divider_width;		/* Width of the bit to divider field */
434};
435
436struct xgene_clk {
437	struct clk_hw	hw;
438	spinlock_t	*lock;
439	struct xgene_dev_parameters	param;
440};
441
442#define to_xgene_clk(_hw) container_of(_hw, struct xgene_clk, hw)
443
444static int xgene_clk_enable(struct clk_hw *hw)
445{
446	struct xgene_clk *pclk = to_xgene_clk(hw);
447	unsigned long flags = 0;
448	u32 data;
449
450	if (pclk->lock)
451		spin_lock_irqsave(pclk->lock, flags);
452
453	if (pclk->param.csr_reg) {
454		pr_debug("%s clock enabled\n", clk_hw_get_name(hw));
455		/* First enable the clock */
456		data = xgene_clk_read(pclk->param.csr_reg +
457					pclk->param.reg_clk_offset);
458		data |= pclk->param.reg_clk_mask;
459		xgene_clk_write(data, pclk->param.csr_reg +
460					pclk->param.reg_clk_offset);
461		pr_debug("%s clk offset 0x%08X mask 0x%08X value 0x%08X\n",
462			clk_hw_get_name(hw),
463			pclk->param.reg_clk_offset, pclk->param.reg_clk_mask,
464			data);
465
466		/* Second enable the CSR */
467		data = xgene_clk_read(pclk->param.csr_reg +
468					pclk->param.reg_csr_offset);
469		data &= ~pclk->param.reg_csr_mask;
470		xgene_clk_write(data, pclk->param.csr_reg +
471					pclk->param.reg_csr_offset);
472		pr_debug("%s csr offset 0x%08X mask 0x%08X value 0x%08X\n",
473			clk_hw_get_name(hw),
474			pclk->param.reg_csr_offset, pclk->param.reg_csr_mask,
475			data);
476	}
477
478	if (pclk->lock)
479		spin_unlock_irqrestore(pclk->lock, flags);
480
481	return 0;
482}
483
484static void xgene_clk_disable(struct clk_hw *hw)
485{
486	struct xgene_clk *pclk = to_xgene_clk(hw);
487	unsigned long flags = 0;
488	u32 data;
489
490	if (pclk->lock)
491		spin_lock_irqsave(pclk->lock, flags);
492
493	if (pclk->param.csr_reg) {
494		pr_debug("%s clock disabled\n", clk_hw_get_name(hw));
495		/* First put the CSR in reset */
496		data = xgene_clk_read(pclk->param.csr_reg +
497					pclk->param.reg_csr_offset);
498		data |= pclk->param.reg_csr_mask;
499		xgene_clk_write(data, pclk->param.csr_reg +
500					pclk->param.reg_csr_offset);
501
502		/* Second disable the clock */
503		data = xgene_clk_read(pclk->param.csr_reg +
504					pclk->param.reg_clk_offset);
505		data &= ~pclk->param.reg_clk_mask;
506		xgene_clk_write(data, pclk->param.csr_reg +
507					pclk->param.reg_clk_offset);
508	}
509
510	if (pclk->lock)
511		spin_unlock_irqrestore(pclk->lock, flags);
512}
513
514static int xgene_clk_is_enabled(struct clk_hw *hw)
515{
516	struct xgene_clk *pclk = to_xgene_clk(hw);
517	u32 data = 0;
518
519	if (pclk->param.csr_reg) {
520		pr_debug("%s clock checking\n", clk_hw_get_name(hw));
521		data = xgene_clk_read(pclk->param.csr_reg +
522					pclk->param.reg_clk_offset);
523		pr_debug("%s clock is %s\n", clk_hw_get_name(hw),
524			data & pclk->param.reg_clk_mask ? "enabled" :
525							"disabled");
526	}
527
528	if (!pclk->param.csr_reg)
529		return 1;
530	return data & pclk->param.reg_clk_mask ? 1 : 0;
531}
532
533static unsigned long xgene_clk_recalc_rate(struct clk_hw *hw,
534				unsigned long parent_rate)
535{
536	struct xgene_clk *pclk = to_xgene_clk(hw);
537	u32 data;
538
539	if (pclk->param.divider_reg) {
540		data = xgene_clk_read(pclk->param.divider_reg +
541					pclk->param.reg_divider_offset);
542		data >>= pclk->param.reg_divider_shift;
543		data &= (1 << pclk->param.reg_divider_width) - 1;
544
545		pr_debug("%s clock recalc rate %ld parent %ld\n",
546			clk_hw_get_name(hw),
547			parent_rate / data, parent_rate);
548
549		return parent_rate / data;
550	} else {
551		pr_debug("%s clock recalc rate %ld parent %ld\n",
552			clk_hw_get_name(hw), parent_rate, parent_rate);
553		return parent_rate;
554	}
555}
556
557static int xgene_clk_set_rate(struct clk_hw *hw, unsigned long rate,
558				unsigned long parent_rate)
559{
560	struct xgene_clk *pclk = to_xgene_clk(hw);
561	unsigned long flags = 0;
562	u32 data;
563	u32 divider;
564	u32 divider_save;
565
566	if (pclk->lock)
567		spin_lock_irqsave(pclk->lock, flags);
568
569	if (pclk->param.divider_reg) {
570		/* Let's compute the divider */
571		if (rate > parent_rate)
572			rate = parent_rate;
573		divider_save = divider = parent_rate / rate; /* Rounded down */
574		divider &= (1 << pclk->param.reg_divider_width) - 1;
575		divider <<= pclk->param.reg_divider_shift;
576
577		/* Set new divider */
578		data = xgene_clk_read(pclk->param.divider_reg +
579				pclk->param.reg_divider_offset);
580		data &= ~(((1 << pclk->param.reg_divider_width) - 1)
581				<< pclk->param.reg_divider_shift);
582		data |= divider;
583		xgene_clk_write(data, pclk->param.divider_reg +
584					pclk->param.reg_divider_offset);
585		pr_debug("%s clock set rate %ld\n", clk_hw_get_name(hw),
586			parent_rate / divider_save);
587	} else {
588		divider_save = 1;
589	}
590
591	if (pclk->lock)
592		spin_unlock_irqrestore(pclk->lock, flags);
593
594	return parent_rate / divider_save;
595}
596
597static long xgene_clk_round_rate(struct clk_hw *hw, unsigned long rate,
598				unsigned long *prate)
599{
600	struct xgene_clk *pclk = to_xgene_clk(hw);
601	unsigned long parent_rate = *prate;
602	u32 divider;
603
604	if (pclk->param.divider_reg) {
605		/* Let's compute the divider */
606		if (rate > parent_rate)
607			rate = parent_rate;
608		divider = parent_rate / rate;   /* Rounded down */
609	} else {
610		divider = 1;
611	}
612
613	return parent_rate / divider;
614}
615
616static const struct clk_ops xgene_clk_ops = {
617	.enable = xgene_clk_enable,
618	.disable = xgene_clk_disable,
619	.is_enabled = xgene_clk_is_enabled,
620	.recalc_rate = xgene_clk_recalc_rate,
621	.set_rate = xgene_clk_set_rate,
622	.round_rate = xgene_clk_round_rate,
623};
624
625static struct clk *xgene_register_clk(struct device *dev,
626		const char *name, const char *parent_name,
627		struct xgene_dev_parameters *parameters, spinlock_t *lock)
628{
629	struct xgene_clk *apmclk;
630	struct clk *clk;
631	struct clk_init_data init;
632	int rc;
633
634	/* allocate the APM clock structure */
635	apmclk = kzalloc(sizeof(*apmclk), GFP_KERNEL);
636	if (!apmclk)
637		return ERR_PTR(-ENOMEM);
638
639	init.name = name;
640	init.ops = &xgene_clk_ops;
641	init.flags = 0;
642	init.parent_names = parent_name ? &parent_name : NULL;
643	init.num_parents = parent_name ? 1 : 0;
644
645	apmclk->lock = lock;
646	apmclk->hw.init = &init;
647	apmclk->param = *parameters;
648
649	/* Register the clock */
650	clk = clk_register(dev, &apmclk->hw);
651	if (IS_ERR(clk)) {
652		pr_err("%s: could not register clk %s\n", __func__, name);
653		kfree(apmclk);
654		return clk;
655	}
656
657	/* Register the clock for lookup */
658	rc = clk_register_clkdev(clk, name, NULL);
659	if (rc != 0) {
660		pr_err("%s: could not register lookup clk %s\n",
661			__func__, name);
662	}
663	return clk;
664}
665
666static void __init xgene_devclk_init(struct device_node *np)
667{
668	const char *clk_name = np->full_name;
669	struct clk *clk;
670	struct resource res;
671	int rc;
672	struct xgene_dev_parameters parameters;
673	int i;
674
675	/* Check if the entry is disabled */
676        if (!of_device_is_available(np))
677                return;
678
679	/* Parse the DTS register for resource */
680	parameters.csr_reg = NULL;
681	parameters.divider_reg = NULL;
682	for (i = 0; i < 2; i++) {
683		void __iomem *map_res;
684		rc = of_address_to_resource(np, i, &res);
685		if (rc != 0) {
686			if (i == 0) {
687				pr_err("no DTS register for %pOF\n", np);
688				return;
689			}
690			break;
691		}
692		map_res = of_iomap(np, i);
693		if (!map_res) {
694			pr_err("Unable to map resource %d for %pOF\n", i, np);
695			goto err;
696		}
697		if (strcmp(res.name, "div-reg") == 0)
698			parameters.divider_reg = map_res;
699		else /* if (strcmp(res->name, "csr-reg") == 0) */
700			parameters.csr_reg = map_res;
701	}
702	if (of_property_read_u32(np, "csr-offset", &parameters.reg_csr_offset))
703		parameters.reg_csr_offset = 0;
704	if (of_property_read_u32(np, "csr-mask", &parameters.reg_csr_mask))
705		parameters.reg_csr_mask = 0xF;
706	if (of_property_read_u32(np, "enable-offset",
707				&parameters.reg_clk_offset))
708		parameters.reg_clk_offset = 0x8;
709	if (of_property_read_u32(np, "enable-mask", &parameters.reg_clk_mask))
710		parameters.reg_clk_mask = 0xF;
711	if (of_property_read_u32(np, "divider-offset",
712				&parameters.reg_divider_offset))
713		parameters.reg_divider_offset = 0;
714	if (of_property_read_u32(np, "divider-width",
715				&parameters.reg_divider_width))
716		parameters.reg_divider_width = 0;
717	if (of_property_read_u32(np, "divider-shift",
718				&parameters.reg_divider_shift))
719		parameters.reg_divider_shift = 0;
720	of_property_read_string(np, "clock-output-names", &clk_name);
721
722	clk = xgene_register_clk(NULL, clk_name,
723		of_clk_get_parent_name(np, 0), &parameters, &clk_lock);
724	if (IS_ERR(clk))
725		goto err;
726	pr_debug("Add %s clock\n", clk_name);
727	rc = of_clk_add_provider(np, of_clk_src_simple_get, clk);
728	if (rc != 0)
729		pr_err("%s: could register provider clk %pOF\n", __func__, np);
730
731	return;
732
733err:
734	if (parameters.csr_reg)
735		iounmap(parameters.csr_reg);
736	if (parameters.divider_reg)
737		iounmap(parameters.divider_reg);
738}
739
740CLK_OF_DECLARE(xgene_socpll_clock, "apm,xgene-socpll-clock", xgene_socpllclk_init);
741CLK_OF_DECLARE(xgene_pcppll_clock, "apm,xgene-pcppll-clock", xgene_pcppllclk_init);
742CLK_OF_DECLARE(xgene_pmd_clock, "apm,xgene-pmd-clock", xgene_pmdclk_init);
743CLK_OF_DECLARE(xgene_socpll_v2_clock, "apm,xgene-socpll-v2-clock",
744	       xgene_socpllclk_init);
745CLK_OF_DECLARE(xgene_pcppll_v2_clock, "apm,xgene-pcppll-v2-clock",
746	       xgene_pcppllclk_init);
747CLK_OF_DECLARE(xgene_dev_clock, "apm,xgene-device-clock", xgene_devclk_init);
748