• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright 2014 Linaro Ltd.
4  * Copyright (C) 2014 ZTE Corporation.
5  */
6 
7 #include <linux/clk-provider.h>
8 #include <linux/err.h>
9 #include <linux/gcd.h>
10 #include <linux/io.h>
11 #include <linux/iopoll.h>
12 #include <linux/slab.h>
13 #include <linux/spinlock.h>
14 #include <asm/div64.h>
15 
16 #include "clk.h"
17 
18 #define to_clk_zx_pll(_hw) container_of(_hw, struct clk_zx_pll, hw)
19 #define to_clk_zx_audio(_hw) container_of(_hw, struct clk_zx_audio, hw)
20 
21 #define CFG0_CFG1_OFFSET 4
22 #define LOCK_FLAG 30
23 #define POWER_DOWN 31
24 
rate_to_idx(struct clk_zx_pll * zx_pll,unsigned long rate)25 static int rate_to_idx(struct clk_zx_pll *zx_pll, unsigned long rate)
26 {
27 	const struct zx_pll_config *config = zx_pll->lookup_table;
28 	int i;
29 
30 	for (i = 0; i < zx_pll->count; i++) {
31 		if (config[i].rate > rate)
32 			return i > 0 ? i - 1 : 0;
33 
34 		if (config[i].rate == rate)
35 			return i;
36 	}
37 
38 	return i - 1;
39 }
40 
hw_to_idx(struct clk_zx_pll * zx_pll)41 static int hw_to_idx(struct clk_zx_pll *zx_pll)
42 {
43 	const struct zx_pll_config *config = zx_pll->lookup_table;
44 	u32 hw_cfg0, hw_cfg1;
45 	int i;
46 
47 	hw_cfg0 = readl_relaxed(zx_pll->reg_base);
48 	hw_cfg1 = readl_relaxed(zx_pll->reg_base + CFG0_CFG1_OFFSET);
49 
50 	/* For matching the value in lookup table */
51 	hw_cfg0 &= ~BIT(zx_pll->lock_bit);
52 
53 	/* Check availability of pd_bit */
54 	if (zx_pll->pd_bit < 32)
55 		hw_cfg0 |= BIT(zx_pll->pd_bit);
56 
57 	for (i = 0; i < zx_pll->count; i++) {
58 		if (hw_cfg0 == config[i].cfg0 && hw_cfg1 == config[i].cfg1)
59 			return i;
60 	}
61 
62 	return -EINVAL;
63 }
64 
zx_pll_recalc_rate(struct clk_hw * hw,unsigned long parent_rate)65 static unsigned long zx_pll_recalc_rate(struct clk_hw *hw,
66 					unsigned long parent_rate)
67 {
68 	struct clk_zx_pll *zx_pll = to_clk_zx_pll(hw);
69 	int idx;
70 
71 	idx = hw_to_idx(zx_pll);
72 	if (unlikely(idx == -EINVAL))
73 		return 0;
74 
75 	return zx_pll->lookup_table[idx].rate;
76 }
77 
zx_pll_round_rate(struct clk_hw * hw,unsigned long rate,unsigned long * prate)78 static long zx_pll_round_rate(struct clk_hw *hw, unsigned long rate,
79 			      unsigned long *prate)
80 {
81 	struct clk_zx_pll *zx_pll = to_clk_zx_pll(hw);
82 	int idx;
83 
84 	idx = rate_to_idx(zx_pll, rate);
85 
86 	return zx_pll->lookup_table[idx].rate;
87 }
88 
zx_pll_set_rate(struct clk_hw * hw,unsigned long rate,unsigned long parent_rate)89 static int zx_pll_set_rate(struct clk_hw *hw, unsigned long rate,
90 			   unsigned long parent_rate)
91 {
92 	/* Assume current cpu is not running on current PLL */
93 	struct clk_zx_pll *zx_pll = to_clk_zx_pll(hw);
94 	const struct zx_pll_config *config;
95 	int idx;
96 
97 	idx = rate_to_idx(zx_pll, rate);
98 	config = &zx_pll->lookup_table[idx];
99 
100 	writel_relaxed(config->cfg0, zx_pll->reg_base);
101 	writel_relaxed(config->cfg1, zx_pll->reg_base + CFG0_CFG1_OFFSET);
102 
103 	return 0;
104 }
105 
zx_pll_enable(struct clk_hw * hw)106 static int zx_pll_enable(struct clk_hw *hw)
107 {
108 	struct clk_zx_pll *zx_pll = to_clk_zx_pll(hw);
109 	u32 reg;
110 
111 	/* If pd_bit is not available, simply return success. */
112 	if (zx_pll->pd_bit > 31)
113 		return 0;
114 
115 	reg = readl_relaxed(zx_pll->reg_base);
116 	writel_relaxed(reg & ~BIT(zx_pll->pd_bit), zx_pll->reg_base);
117 
118 	return readl_relaxed_poll_timeout(zx_pll->reg_base, reg,
119 					  reg & BIT(zx_pll->lock_bit), 0, 100);
120 }
121 
zx_pll_disable(struct clk_hw * hw)122 static void zx_pll_disable(struct clk_hw *hw)
123 {
124 	struct clk_zx_pll *zx_pll = to_clk_zx_pll(hw);
125 	u32 reg;
126 
127 	if (zx_pll->pd_bit > 31)
128 		return;
129 
130 	reg = readl_relaxed(zx_pll->reg_base);
131 	writel_relaxed(reg | BIT(zx_pll->pd_bit), zx_pll->reg_base);
132 }
133 
zx_pll_is_enabled(struct clk_hw * hw)134 static int zx_pll_is_enabled(struct clk_hw *hw)
135 {
136 	struct clk_zx_pll *zx_pll = to_clk_zx_pll(hw);
137 	u32 reg;
138 
139 	reg = readl_relaxed(zx_pll->reg_base);
140 
141 	return !(reg & BIT(zx_pll->pd_bit));
142 }
143 
144 const struct clk_ops zx_pll_ops = {
145 	.recalc_rate = zx_pll_recalc_rate,
146 	.round_rate = zx_pll_round_rate,
147 	.set_rate = zx_pll_set_rate,
148 	.enable = zx_pll_enable,
149 	.disable = zx_pll_disable,
150 	.is_enabled = zx_pll_is_enabled,
151 };
152 EXPORT_SYMBOL(zx_pll_ops);
153 
clk_register_zx_pll(const char * name,const char * parent_name,unsigned long flags,void __iomem * reg_base,const struct zx_pll_config * lookup_table,int count,spinlock_t * lock)154 struct clk *clk_register_zx_pll(const char *name, const char *parent_name,
155 				unsigned long flags, void __iomem *reg_base,
156 				const struct zx_pll_config *lookup_table,
157 				int count, spinlock_t *lock)
158 {
159 	struct clk_zx_pll *zx_pll;
160 	struct clk *clk;
161 	struct clk_init_data init;
162 
163 	zx_pll = kzalloc(sizeof(*zx_pll), GFP_KERNEL);
164 	if (!zx_pll)
165 		return ERR_PTR(-ENOMEM);
166 
167 	init.name = name;
168 	init.ops = &zx_pll_ops;
169 	init.flags = flags;
170 	init.parent_names = parent_name ? &parent_name : NULL;
171 	init.num_parents = parent_name ? 1 : 0;
172 
173 	zx_pll->reg_base = reg_base;
174 	zx_pll->lookup_table = lookup_table;
175 	zx_pll->count = count;
176 	zx_pll->lock_bit = LOCK_FLAG;
177 	zx_pll->pd_bit = POWER_DOWN;
178 	zx_pll->lock = lock;
179 	zx_pll->hw.init = &init;
180 
181 	clk = clk_register(NULL, &zx_pll->hw);
182 	if (IS_ERR(clk))
183 		kfree(zx_pll);
184 
185 	return clk;
186 }
187 
188 #define BPAR 1000000
calc_reg(u32 parent_rate,u32 rate)189 static u32 calc_reg(u32 parent_rate, u32 rate)
190 {
191 	u32 sel, integ, fra_div, tmp;
192 	u64 tmp64 = (u64)parent_rate * BPAR;
193 
194 	do_div(tmp64, rate);
195 	integ = (u32)tmp64 / BPAR;
196 	integ = integ >> 1;
197 
198 	tmp = (u32)tmp64 % BPAR;
199 	sel = tmp / BPAR;
200 
201 	tmp = tmp % BPAR;
202 	fra_div = tmp * 0xff / BPAR;
203 	tmp = (sel << 24) | (integ << 16) | (0xff << 8) | fra_div;
204 
205 	/* Set I2S integer divider as 1. This bit is reserved for SPDIF
206 	 * and do no harm.
207 	 */
208 	tmp |= BIT(28);
209 	return tmp;
210 }
211 
calc_rate(u32 reg,u32 parent_rate)212 static u32 calc_rate(u32 reg, u32 parent_rate)
213 {
214 	u32 sel, integ, fra_div, tmp;
215 	u64 tmp64 = (u64)parent_rate * BPAR;
216 
217 	tmp = reg;
218 	sel = (tmp >> 24) & BIT(0);
219 	integ = (tmp >> 16) & 0xff;
220 	fra_div = tmp & 0xff;
221 
222 	tmp = fra_div * BPAR;
223 	tmp = tmp / 0xff;
224 	tmp += sel * BPAR;
225 	tmp += 2 * integ * BPAR;
226 	do_div(tmp64, tmp);
227 
228 	return (u32)tmp64;
229 }
230 
zx_audio_recalc_rate(struct clk_hw * hw,unsigned long parent_rate)231 static unsigned long zx_audio_recalc_rate(struct clk_hw *hw,
232 					  unsigned long parent_rate)
233 {
234 	struct clk_zx_audio *zx_audio = to_clk_zx_audio(hw);
235 	u32 reg;
236 
237 	reg = readl_relaxed(zx_audio->reg_base);
238 	return calc_rate(reg, parent_rate);
239 }
240 
zx_audio_round_rate(struct clk_hw * hw,unsigned long rate,unsigned long * prate)241 static long zx_audio_round_rate(struct clk_hw *hw, unsigned long rate,
242 				unsigned long *prate)
243 {
244 	u32 reg;
245 
246 	if (rate * 2 > *prate)
247 		return -EINVAL;
248 
249 	reg = calc_reg(*prate, rate);
250 	return calc_rate(reg, *prate);
251 }
252 
zx_audio_set_rate(struct clk_hw * hw,unsigned long rate,unsigned long parent_rate)253 static int zx_audio_set_rate(struct clk_hw *hw, unsigned long rate,
254 			     unsigned long parent_rate)
255 {
256 	struct clk_zx_audio *zx_audio = to_clk_zx_audio(hw);
257 	u32 reg;
258 
259 	reg = calc_reg(parent_rate, rate);
260 	writel_relaxed(reg, zx_audio->reg_base);
261 
262 	return 0;
263 }
264 
265 #define ZX_AUDIO_EN BIT(25)
zx_audio_enable(struct clk_hw * hw)266 static int zx_audio_enable(struct clk_hw *hw)
267 {
268 	struct clk_zx_audio *zx_audio = to_clk_zx_audio(hw);
269 	u32 reg;
270 
271 	reg = readl_relaxed(zx_audio->reg_base);
272 	writel_relaxed(reg & ~ZX_AUDIO_EN, zx_audio->reg_base);
273 	return 0;
274 }
275 
zx_audio_disable(struct clk_hw * hw)276 static void zx_audio_disable(struct clk_hw *hw)
277 {
278 	struct clk_zx_audio *zx_audio = to_clk_zx_audio(hw);
279 	u32 reg;
280 
281 	reg = readl_relaxed(zx_audio->reg_base);
282 	writel_relaxed(reg | ZX_AUDIO_EN, zx_audio->reg_base);
283 }
284 
285 static const struct clk_ops zx_audio_ops = {
286 	.recalc_rate = zx_audio_recalc_rate,
287 	.round_rate = zx_audio_round_rate,
288 	.set_rate = zx_audio_set_rate,
289 	.enable = zx_audio_enable,
290 	.disable = zx_audio_disable,
291 };
292 
clk_register_zx_audio(const char * name,const char * const parent_name,unsigned long flags,void __iomem * reg_base)293 struct clk *clk_register_zx_audio(const char *name,
294 				  const char * const parent_name,
295 				  unsigned long flags,
296 				  void __iomem *reg_base)
297 {
298 	struct clk_zx_audio *zx_audio;
299 	struct clk *clk;
300 	struct clk_init_data init;
301 
302 	zx_audio = kzalloc(sizeof(*zx_audio), GFP_KERNEL);
303 	if (!zx_audio)
304 		return ERR_PTR(-ENOMEM);
305 
306 	init.name = name;
307 	init.ops = &zx_audio_ops;
308 	init.flags = flags;
309 	init.parent_names = parent_name ? &parent_name : NULL;
310 	init.num_parents = parent_name ? 1 : 0;
311 
312 	zx_audio->reg_base = reg_base;
313 	zx_audio->hw.init = &init;
314 
315 	clk = clk_register(NULL, &zx_audio->hw);
316 	if (IS_ERR(clk))
317 		kfree(zx_audio);
318 
319 	return clk;
320 }
321 
322 #define CLK_AUDIO_DIV_FRAC	BIT(0)
323 #define CLK_AUDIO_DIV_INT	BIT(1)
324 #define CLK_AUDIO_DIV_UNCOMMON	BIT(1)
325 
326 #define CLK_AUDIO_DIV_FRAC_NSHIFT	16
327 #define CLK_AUDIO_DIV_INT_FRAC_RE	BIT(16)
328 #define CLK_AUDIO_DIV_INT_FRAC_MAX	(0xffff)
329 #define CLK_AUDIO_DIV_INT_FRAC_MIN	(0x2)
330 #define CLK_AUDIO_DIV_INT_INT_SHIFT	24
331 #define CLK_AUDIO_DIV_INT_INT_WIDTH	4
332 
333 struct zx_clk_audio_div_table {
334 	unsigned long rate;
335 	unsigned int int_reg;
336 	unsigned int frac_reg;
337 };
338 
339 #define to_clk_zx_audio_div(_hw) container_of(_hw, struct clk_zx_audio_divider, hw)
340 
audio_calc_rate(struct clk_zx_audio_divider * audio_div,u32 reg_frac,u32 reg_int,unsigned long parent_rate)341 static unsigned long audio_calc_rate(struct clk_zx_audio_divider *audio_div,
342 				     u32 reg_frac, u32 reg_int,
343 				     unsigned long parent_rate)
344 {
345 	unsigned long rate, m, n;
346 
347 	m = reg_frac & 0xffff;
348 	n = (reg_frac >> 16) & 0xffff;
349 
350 	m = (reg_int & 0xffff) * n + m;
351 	rate = (parent_rate * n) / m;
352 
353 	return rate;
354 }
355 
audio_calc_reg(struct clk_zx_audio_divider * audio_div,struct zx_clk_audio_div_table * div_table,unsigned long rate,unsigned long parent_rate)356 static void audio_calc_reg(struct clk_zx_audio_divider *audio_div,
357 			   struct zx_clk_audio_div_table *div_table,
358 			   unsigned long rate, unsigned long parent_rate)
359 {
360 	unsigned int reg_int, reg_frac;
361 	unsigned long m, n, div;
362 
363 	reg_int = parent_rate / rate;
364 
365 	if (reg_int > CLK_AUDIO_DIV_INT_FRAC_MAX)
366 		reg_int = CLK_AUDIO_DIV_INT_FRAC_MAX;
367 	else if (reg_int < CLK_AUDIO_DIV_INT_FRAC_MIN)
368 		reg_int = 0;
369 	m = parent_rate - rate * reg_int;
370 	n = rate;
371 
372 	div = gcd(m, n);
373 	m = m / div;
374 	n = n / div;
375 
376 	if ((m >> 16) || (n >> 16)) {
377 		if (m > n) {
378 			n = n * 0xffff / m;
379 			m = 0xffff;
380 		} else {
381 			m = m * 0xffff / n;
382 			n = 0xffff;
383 		}
384 	}
385 	reg_frac = m | (n << 16);
386 
387 	div_table->rate = parent_rate * n / (reg_int * n + m);
388 	div_table->int_reg = reg_int;
389 	div_table->frac_reg = reg_frac;
390 }
391 
zx_audio_div_recalc_rate(struct clk_hw * hw,unsigned long parent_rate)392 static unsigned long zx_audio_div_recalc_rate(struct clk_hw *hw,
393 					  unsigned long parent_rate)
394 {
395 	struct clk_zx_audio_divider *zx_audio_div = to_clk_zx_audio_div(hw);
396 	u32 reg_frac, reg_int;
397 
398 	reg_frac = readl_relaxed(zx_audio_div->reg_base);
399 	reg_int = readl_relaxed(zx_audio_div->reg_base + 0x4);
400 
401 	return audio_calc_rate(zx_audio_div, reg_frac, reg_int, parent_rate);
402 }
403 
zx_audio_div_round_rate(struct clk_hw * hw,unsigned long rate,unsigned long * prate)404 static long zx_audio_div_round_rate(struct clk_hw *hw, unsigned long rate,
405 				unsigned long *prate)
406 {
407 	struct clk_zx_audio_divider *zx_audio_div = to_clk_zx_audio_div(hw);
408 	struct zx_clk_audio_div_table divt;
409 
410 	audio_calc_reg(zx_audio_div, &divt, rate, *prate);
411 
412 	return audio_calc_rate(zx_audio_div, divt.frac_reg, divt.int_reg, *prate);
413 }
414 
zx_audio_div_set_rate(struct clk_hw * hw,unsigned long rate,unsigned long parent_rate)415 static int zx_audio_div_set_rate(struct clk_hw *hw, unsigned long rate,
416 				    unsigned long parent_rate)
417 {
418 	struct clk_zx_audio_divider *zx_audio_div = to_clk_zx_audio_div(hw);
419 	struct zx_clk_audio_div_table divt;
420 	unsigned int val;
421 
422 	audio_calc_reg(zx_audio_div, &divt, rate, parent_rate);
423 	if (divt.rate != rate)
424 		pr_debug("the real rate is:%ld", divt.rate);
425 
426 	writel_relaxed(divt.frac_reg, zx_audio_div->reg_base);
427 
428 	val = readl_relaxed(zx_audio_div->reg_base + 0x4);
429 	val &= ~0xffff;
430 	val |= divt.int_reg | CLK_AUDIO_DIV_INT_FRAC_RE;
431 	writel_relaxed(val, zx_audio_div->reg_base + 0x4);
432 
433 	mdelay(1);
434 
435 	val = readl_relaxed(zx_audio_div->reg_base + 0x4);
436 	val &= ~CLK_AUDIO_DIV_INT_FRAC_RE;
437 	writel_relaxed(val, zx_audio_div->reg_base + 0x4);
438 
439 	return 0;
440 }
441 
442 const struct clk_ops zx_audio_div_ops = {
443 	.recalc_rate = zx_audio_div_recalc_rate,
444 	.round_rate = zx_audio_div_round_rate,
445 	.set_rate = zx_audio_div_set_rate,
446 };
447