• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
3  *  JZ4740 SoC clock support
4  *
5  *  This program is free software; you can redistribute it and/or modify it
6  *  under  the terms of the GNU General	 Public License as published by the
7  *  Free Software Foundation;  either version 2 of the License, or (at your
8  *  option) any later version.
9  *
10  *  You should have received a copy of the GNU General Public License along
11  *  with this program; if not, write to the Free Software Foundation, Inc.,
12  *  675 Mass Ave, Cambridge, MA 02139, USA.
13  *
14  */
15 
16 #include <linux/kernel.h>
17 #include <linux/errno.h>
18 #include <linux/clk.h>
19 #include <linux/spinlock.h>
20 #include <linux/io.h>
21 #include <linux/module.h>
22 #include <linux/list.h>
23 #include <linux/err.h>
24 
25 #include <asm/mach-jz4740/clock.h>
26 #include <asm/mach-jz4740/base.h>
27 
28 #include "clock.h"
29 
30 #define JZ_REG_CLOCK_CTRL	0x00
31 #define JZ_REG_CLOCK_LOW_POWER	0x04
32 #define JZ_REG_CLOCK_PLL	0x10
33 #define JZ_REG_CLOCK_GATE	0x20
34 #define JZ_REG_CLOCK_SLEEP_CTRL 0x24
35 #define JZ_REG_CLOCK_I2S	0x60
36 #define JZ_REG_CLOCK_LCD	0x64
37 #define JZ_REG_CLOCK_MMC	0x68
38 #define JZ_REG_CLOCK_UHC	0x6C
39 #define JZ_REG_CLOCK_SPI	0x74
40 
41 #define JZ_CLOCK_CTRL_I2S_SRC_PLL	BIT(31)
42 #define JZ_CLOCK_CTRL_KO_ENABLE		BIT(30)
43 #define JZ_CLOCK_CTRL_UDC_SRC_PLL	BIT(29)
44 #define JZ_CLOCK_CTRL_UDIV_MASK		0x1f800000
45 #define JZ_CLOCK_CTRL_CHANGE_ENABLE	BIT(22)
46 #define JZ_CLOCK_CTRL_PLL_HALF		BIT(21)
47 #define JZ_CLOCK_CTRL_LDIV_MASK		0x001f0000
48 #define JZ_CLOCK_CTRL_UDIV_OFFSET	23
49 #define JZ_CLOCK_CTRL_LDIV_OFFSET	16
50 #define JZ_CLOCK_CTRL_MDIV_OFFSET	12
51 #define JZ_CLOCK_CTRL_PDIV_OFFSET	 8
52 #define JZ_CLOCK_CTRL_HDIV_OFFSET	 4
53 #define JZ_CLOCK_CTRL_CDIV_OFFSET	 0
54 
55 #define JZ_CLOCK_GATE_UART0	BIT(0)
56 #define JZ_CLOCK_GATE_TCU	BIT(1)
57 #define JZ_CLOCK_GATE_RTC	BIT(2)
58 #define JZ_CLOCK_GATE_I2C	BIT(3)
59 #define JZ_CLOCK_GATE_SPI	BIT(4)
60 #define JZ_CLOCK_GATE_AIC	BIT(5)
61 #define JZ_CLOCK_GATE_I2S	BIT(6)
62 #define JZ_CLOCK_GATE_MMC	BIT(7)
63 #define JZ_CLOCK_GATE_ADC	BIT(8)
64 #define JZ_CLOCK_GATE_CIM	BIT(9)
65 #define JZ_CLOCK_GATE_LCD	BIT(10)
66 #define JZ_CLOCK_GATE_UDC	BIT(11)
67 #define JZ_CLOCK_GATE_DMAC	BIT(12)
68 #define JZ_CLOCK_GATE_IPU	BIT(13)
69 #define JZ_CLOCK_GATE_UHC	BIT(14)
70 #define JZ_CLOCK_GATE_UART1	BIT(15)
71 
72 #define JZ_CLOCK_I2S_DIV_MASK		0x01ff
73 
74 #define JZ_CLOCK_LCD_DIV_MASK		0x01ff
75 
76 #define JZ_CLOCK_MMC_DIV_MASK		0x001f
77 
78 #define JZ_CLOCK_UHC_DIV_MASK		0x000f
79 
80 #define JZ_CLOCK_SPI_SRC_PLL		BIT(31)
81 #define JZ_CLOCK_SPI_DIV_MASK		0x000f
82 
83 #define JZ_CLOCK_PLL_M_MASK		0x01ff
84 #define JZ_CLOCK_PLL_N_MASK		0x001f
85 #define JZ_CLOCK_PLL_OD_MASK		0x0003
86 #define JZ_CLOCK_PLL_STABLE		BIT(10)
87 #define JZ_CLOCK_PLL_BYPASS		BIT(9)
88 #define JZ_CLOCK_PLL_ENABLED		BIT(8)
89 #define JZ_CLOCK_PLL_STABLIZE_MASK	0x000f
90 #define JZ_CLOCK_PLL_M_OFFSET		23
91 #define JZ_CLOCK_PLL_N_OFFSET		18
92 #define JZ_CLOCK_PLL_OD_OFFSET		16
93 
94 #define JZ_CLOCK_LOW_POWER_MODE_DOZE BIT(2)
95 #define JZ_CLOCK_LOW_POWER_MODE_SLEEP BIT(0)
96 
97 #define JZ_CLOCK_SLEEP_CTRL_SUSPEND_UHC BIT(7)
98 #define JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC BIT(6)
99 
100 static void __iomem *jz_clock_base;
101 static spinlock_t jz_clock_lock;
102 static LIST_HEAD(jz_clocks);
103 
104 struct main_clk {
105 	struct clk clk;
106 	uint32_t div_offset;
107 };
108 
109 struct divided_clk {
110 	struct clk clk;
111 	uint32_t reg;
112 	uint32_t mask;
113 };
114 
115 struct static_clk {
116 	struct clk clk;
117 	unsigned long rate;
118 };
119 
jz_clk_reg_read(int reg)120 static uint32_t jz_clk_reg_read(int reg)
121 {
122 	return readl(jz_clock_base + reg);
123 }
124 
jz_clk_reg_write_mask(int reg,uint32_t val,uint32_t mask)125 static void jz_clk_reg_write_mask(int reg, uint32_t val, uint32_t mask)
126 {
127 	uint32_t val2;
128 
129 	spin_lock(&jz_clock_lock);
130 	val2 = readl(jz_clock_base + reg);
131 	val2 &= ~mask;
132 	val2 |= val;
133 	writel(val2, jz_clock_base + reg);
134 	spin_unlock(&jz_clock_lock);
135 }
136 
jz_clk_reg_set_bits(int reg,uint32_t mask)137 static void jz_clk_reg_set_bits(int reg, uint32_t mask)
138 {
139 	uint32_t val;
140 
141 	spin_lock(&jz_clock_lock);
142 	val = readl(jz_clock_base + reg);
143 	val |= mask;
144 	writel(val, jz_clock_base + reg);
145 	spin_unlock(&jz_clock_lock);
146 }
147 
jz_clk_reg_clear_bits(int reg,uint32_t mask)148 static void jz_clk_reg_clear_bits(int reg, uint32_t mask)
149 {
150 	uint32_t val;
151 
152 	spin_lock(&jz_clock_lock);
153 	val = readl(jz_clock_base + reg);
154 	val &= ~mask;
155 	writel(val, jz_clock_base + reg);
156 	spin_unlock(&jz_clock_lock);
157 }
158 
jz_clk_enable_gating(struct clk * clk)159 static int jz_clk_enable_gating(struct clk *clk)
160 {
161 	if (clk->gate_bit == JZ4740_CLK_NOT_GATED)
162 		return -EINVAL;
163 
164 	jz_clk_reg_clear_bits(JZ_REG_CLOCK_GATE, clk->gate_bit);
165 	return 0;
166 }
167 
jz_clk_disable_gating(struct clk * clk)168 static int jz_clk_disable_gating(struct clk *clk)
169 {
170 	if (clk->gate_bit == JZ4740_CLK_NOT_GATED)
171 		return -EINVAL;
172 
173 	jz_clk_reg_set_bits(JZ_REG_CLOCK_GATE, clk->gate_bit);
174 	return 0;
175 }
176 
jz_clk_is_enabled_gating(struct clk * clk)177 static int jz_clk_is_enabled_gating(struct clk *clk)
178 {
179 	if (clk->gate_bit == JZ4740_CLK_NOT_GATED)
180 		return 1;
181 
182 	return !(jz_clk_reg_read(JZ_REG_CLOCK_GATE) & clk->gate_bit);
183 }
184 
jz_clk_static_get_rate(struct clk * clk)185 static unsigned long jz_clk_static_get_rate(struct clk *clk)
186 {
187 	return ((struct static_clk *)clk)->rate;
188 }
189 
jz_clk_ko_enable(struct clk * clk)190 static int jz_clk_ko_enable(struct clk *clk)
191 {
192 	jz_clk_reg_set_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_KO_ENABLE);
193 	return 0;
194 }
195 
jz_clk_ko_disable(struct clk * clk)196 static int jz_clk_ko_disable(struct clk *clk)
197 {
198 	jz_clk_reg_clear_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_KO_ENABLE);
199 	return 0;
200 }
201 
jz_clk_ko_is_enabled(struct clk * clk)202 static int jz_clk_ko_is_enabled(struct clk *clk)
203 {
204 	return !!(jz_clk_reg_read(JZ_REG_CLOCK_CTRL) & JZ_CLOCK_CTRL_KO_ENABLE);
205 }
206 
207 static const int pllno[] = {1, 2, 2, 4};
208 
jz_clk_pll_get_rate(struct clk * clk)209 static unsigned long jz_clk_pll_get_rate(struct clk *clk)
210 {
211 	uint32_t val;
212 	int m;
213 	int n;
214 	int od;
215 
216 	val = jz_clk_reg_read(JZ_REG_CLOCK_PLL);
217 
218 	if (val & JZ_CLOCK_PLL_BYPASS)
219 		return clk_get_rate(clk->parent);
220 
221 	m = ((val >> 23) & 0x1ff) + 2;
222 	n = ((val >> 18) & 0x1f) + 2;
223 	od = (val >> 16) & 0x3;
224 
225 	return ((clk_get_rate(clk->parent) / n) * m) / pllno[od];
226 }
227 
jz_clk_pll_half_get_rate(struct clk * clk)228 static unsigned long jz_clk_pll_half_get_rate(struct clk *clk)
229 {
230 	uint32_t reg;
231 
232 	reg = jz_clk_reg_read(JZ_REG_CLOCK_CTRL);
233 	if (reg & JZ_CLOCK_CTRL_PLL_HALF)
234 		return jz_clk_pll_get_rate(clk->parent);
235 	return jz_clk_pll_get_rate(clk->parent) >> 1;
236 }
237 
238 static const int jz_clk_main_divs[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32};
239 
jz_clk_main_round_rate(struct clk * clk,unsigned long rate)240 static unsigned long jz_clk_main_round_rate(struct clk *clk, unsigned long rate)
241 {
242 	unsigned long parent_rate = jz_clk_pll_get_rate(clk->parent);
243 	int div;
244 
245 	div = parent_rate / rate;
246 	if (div > 32)
247 		return parent_rate / 32;
248 	else if (div < 1)
249 		return parent_rate;
250 
251 	div &= (0x3 << (ffs(div) - 1));
252 
253 	return parent_rate / div;
254 }
255 
jz_clk_main_get_rate(struct clk * clk)256 static unsigned long jz_clk_main_get_rate(struct clk *clk)
257 {
258 	struct main_clk *mclk = (struct main_clk *)clk;
259 	uint32_t div;
260 
261 	div = jz_clk_reg_read(JZ_REG_CLOCK_CTRL);
262 
263 	div >>= mclk->div_offset;
264 	div &= 0xf;
265 
266 	if (div >= ARRAY_SIZE(jz_clk_main_divs))
267 		div = ARRAY_SIZE(jz_clk_main_divs) - 1;
268 
269 	return jz_clk_pll_get_rate(clk->parent) / jz_clk_main_divs[div];
270 }
271 
jz_clk_main_set_rate(struct clk * clk,unsigned long rate)272 static int jz_clk_main_set_rate(struct clk *clk, unsigned long rate)
273 {
274 	struct main_clk *mclk = (struct main_clk *)clk;
275 	int i;
276 	int div;
277 	unsigned long parent_rate = jz_clk_pll_get_rate(clk->parent);
278 
279 	rate = jz_clk_main_round_rate(clk, rate);
280 
281 	div = parent_rate / rate;
282 
283 	i = (ffs(div) - 1) << 1;
284 	if (i > 0 && !(div & BIT(i-1)))
285 		i -= 1;
286 
287 	jz_clk_reg_write_mask(JZ_REG_CLOCK_CTRL, i << mclk->div_offset,
288 				0xf << mclk->div_offset);
289 
290 	return 0;
291 }
292 
293 static struct clk_ops jz_clk_static_ops = {
294 	.get_rate = jz_clk_static_get_rate,
295 	.enable = jz_clk_enable_gating,
296 	.disable = jz_clk_disable_gating,
297 	.is_enabled = jz_clk_is_enabled_gating,
298 };
299 
300 static struct static_clk jz_clk_ext = {
301 	.clk = {
302 		.name = "ext",
303 		.gate_bit = JZ4740_CLK_NOT_GATED,
304 		.ops = &jz_clk_static_ops,
305 	},
306 };
307 
308 static struct clk_ops jz_clk_pll_ops = {
309 	.get_rate = jz_clk_pll_get_rate,
310 };
311 
312 static struct clk jz_clk_pll = {
313 	.name = "pll",
314 	.parent = &jz_clk_ext.clk,
315 	.ops = &jz_clk_pll_ops,
316 };
317 
318 static struct clk_ops jz_clk_pll_half_ops = {
319 	.get_rate = jz_clk_pll_half_get_rate,
320 };
321 
322 static struct clk jz_clk_pll_half = {
323 	.name = "pll half",
324 	.parent = &jz_clk_pll,
325 	.ops = &jz_clk_pll_half_ops,
326 };
327 
328 static const struct clk_ops jz_clk_main_ops = {
329 	.get_rate = jz_clk_main_get_rate,
330 	.set_rate = jz_clk_main_set_rate,
331 	.round_rate = jz_clk_main_round_rate,
332 };
333 
334 static struct main_clk jz_clk_cpu = {
335 	.clk = {
336 		.name = "cclk",
337 		.parent = &jz_clk_pll,
338 		.ops = &jz_clk_main_ops,
339 	},
340 	.div_offset = JZ_CLOCK_CTRL_CDIV_OFFSET,
341 };
342 
343 static struct main_clk jz_clk_memory = {
344 	.clk = {
345 		.name = "mclk",
346 		.parent = &jz_clk_pll,
347 		.ops = &jz_clk_main_ops,
348 	},
349 	.div_offset = JZ_CLOCK_CTRL_MDIV_OFFSET,
350 };
351 
352 static struct main_clk jz_clk_high_speed_peripheral = {
353 	.clk = {
354 		.name = "hclk",
355 		.parent = &jz_clk_pll,
356 		.ops = &jz_clk_main_ops,
357 	},
358 	.div_offset = JZ_CLOCK_CTRL_HDIV_OFFSET,
359 };
360 
361 
362 static struct main_clk jz_clk_low_speed_peripheral = {
363 	.clk = {
364 		.name = "pclk",
365 		.parent = &jz_clk_pll,
366 		.ops = &jz_clk_main_ops,
367 	},
368 	.div_offset = JZ_CLOCK_CTRL_PDIV_OFFSET,
369 };
370 
371 static const struct clk_ops jz_clk_ko_ops = {
372 	.enable = jz_clk_ko_enable,
373 	.disable = jz_clk_ko_disable,
374 	.is_enabled = jz_clk_ko_is_enabled,
375 };
376 
377 static struct clk jz_clk_ko = {
378 	.name = "cko",
379 	.parent = &jz_clk_memory.clk,
380 	.ops = &jz_clk_ko_ops,
381 };
382 
jz_clk_spi_set_parent(struct clk * clk,struct clk * parent)383 static int jz_clk_spi_set_parent(struct clk *clk, struct clk *parent)
384 {
385 	if (parent == &jz_clk_pll)
386 		jz_clk_reg_set_bits(JZ_CLOCK_SPI_SRC_PLL, JZ_REG_CLOCK_SPI);
387 	else if (parent == &jz_clk_ext.clk)
388 		jz_clk_reg_clear_bits(JZ_CLOCK_SPI_SRC_PLL, JZ_REG_CLOCK_SPI);
389 	else
390 		return -EINVAL;
391 
392 	clk->parent = parent;
393 
394 	return 0;
395 }
396 
jz_clk_i2s_set_parent(struct clk * clk,struct clk * parent)397 static int jz_clk_i2s_set_parent(struct clk *clk, struct clk *parent)
398 {
399 	if (parent == &jz_clk_pll_half)
400 		jz_clk_reg_set_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_I2S_SRC_PLL);
401 	else if (parent == &jz_clk_ext.clk)
402 		jz_clk_reg_clear_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_I2S_SRC_PLL);
403 	else
404 		return -EINVAL;
405 
406 	clk->parent = parent;
407 
408 	return 0;
409 }
410 
jz_clk_udc_enable(struct clk * clk)411 static int jz_clk_udc_enable(struct clk *clk)
412 {
413 	jz_clk_reg_set_bits(JZ_REG_CLOCK_SLEEP_CTRL,
414 			JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC);
415 
416 	return 0;
417 }
418 
jz_clk_udc_disable(struct clk * clk)419 static int jz_clk_udc_disable(struct clk *clk)
420 {
421 	jz_clk_reg_clear_bits(JZ_REG_CLOCK_SLEEP_CTRL,
422 			JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC);
423 
424 	return 0;
425 }
426 
jz_clk_udc_is_enabled(struct clk * clk)427 static int jz_clk_udc_is_enabled(struct clk *clk)
428 {
429 	return !!(jz_clk_reg_read(JZ_REG_CLOCK_SLEEP_CTRL) &
430 			JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC);
431 }
432 
jz_clk_udc_set_parent(struct clk * clk,struct clk * parent)433 static int jz_clk_udc_set_parent(struct clk *clk, struct clk *parent)
434 {
435 	if (parent == &jz_clk_pll_half)
436 		jz_clk_reg_set_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_UDC_SRC_PLL);
437 	else if (parent == &jz_clk_ext.clk)
438 		jz_clk_reg_clear_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_UDC_SRC_PLL);
439 	else
440 		return -EINVAL;
441 
442 	clk->parent = parent;
443 
444 	return 0;
445 }
446 
jz_clk_udc_set_rate(struct clk * clk,unsigned long rate)447 static int jz_clk_udc_set_rate(struct clk *clk, unsigned long rate)
448 {
449 	int div;
450 
451 	if (clk->parent == &jz_clk_ext.clk)
452 		return -EINVAL;
453 
454 	div = clk_get_rate(clk->parent) / rate - 1;
455 
456 	if (div < 0)
457 		div = 0;
458 	else if (div > 63)
459 		div = 63;
460 
461 	jz_clk_reg_write_mask(JZ_REG_CLOCK_CTRL, div << JZ_CLOCK_CTRL_UDIV_OFFSET,
462 				JZ_CLOCK_CTRL_UDIV_MASK);
463 	return 0;
464 }
465 
jz_clk_udc_get_rate(struct clk * clk)466 static unsigned long jz_clk_udc_get_rate(struct clk *clk)
467 {
468 	int div;
469 
470 	if (clk->parent == &jz_clk_ext.clk)
471 		return clk_get_rate(clk->parent);
472 
473 	div = (jz_clk_reg_read(JZ_REG_CLOCK_CTRL) & JZ_CLOCK_CTRL_UDIV_MASK);
474 	div >>= JZ_CLOCK_CTRL_UDIV_OFFSET;
475 	div += 1;
476 
477 	return clk_get_rate(clk->parent) / div;
478 }
479 
jz_clk_divided_get_rate(struct clk * clk)480 static unsigned long jz_clk_divided_get_rate(struct clk *clk)
481 {
482 	struct divided_clk *dclk = (struct divided_clk *)clk;
483 	int div;
484 
485 	if (clk->parent == &jz_clk_ext.clk)
486 		return clk_get_rate(clk->parent);
487 
488 	div = (jz_clk_reg_read(dclk->reg) & dclk->mask) + 1;
489 
490 	return clk_get_rate(clk->parent) / div;
491 }
492 
jz_clk_divided_set_rate(struct clk * clk,unsigned long rate)493 static int jz_clk_divided_set_rate(struct clk *clk, unsigned long rate)
494 {
495 	struct divided_clk *dclk = (struct divided_clk *)clk;
496 	int div;
497 
498 	if (clk->parent == &jz_clk_ext.clk)
499 		return -EINVAL;
500 
501 	div = clk_get_rate(clk->parent) / rate - 1;
502 
503 	if (div < 0)
504 		div = 0;
505 	else if (div > dclk->mask)
506 		div = dclk->mask;
507 
508 	jz_clk_reg_write_mask(dclk->reg, div, dclk->mask);
509 
510 	return 0;
511 }
512 
jz_clk_ldclk_round_rate(struct clk * clk,unsigned long rate)513 static unsigned long jz_clk_ldclk_round_rate(struct clk *clk, unsigned long rate)
514 {
515 	int div;
516 	unsigned long parent_rate = jz_clk_pll_half_get_rate(clk->parent);
517 
518 	if (rate > 150000000)
519 		return 150000000;
520 
521 	div = parent_rate / rate;
522 	if (div < 1)
523 		div = 1;
524 	else if (div > 32)
525 		div = 32;
526 
527 	return parent_rate / div;
528 }
529 
jz_clk_ldclk_set_rate(struct clk * clk,unsigned long rate)530 static int jz_clk_ldclk_set_rate(struct clk *clk, unsigned long rate)
531 {
532 	int div;
533 
534 	if (rate > 150000000)
535 		return -EINVAL;
536 
537 	div = jz_clk_pll_half_get_rate(clk->parent) / rate - 1;
538 	if (div < 0)
539 		div = 0;
540 	else if (div > 31)
541 		div = 31;
542 
543 	jz_clk_reg_write_mask(JZ_REG_CLOCK_CTRL, div << JZ_CLOCK_CTRL_LDIV_OFFSET,
544 				JZ_CLOCK_CTRL_LDIV_MASK);
545 
546 	return 0;
547 }
548 
jz_clk_ldclk_get_rate(struct clk * clk)549 static unsigned long jz_clk_ldclk_get_rate(struct clk *clk)
550 {
551 	int div;
552 
553 	div = jz_clk_reg_read(JZ_REG_CLOCK_CTRL) & JZ_CLOCK_CTRL_LDIV_MASK;
554 	div >>= JZ_CLOCK_CTRL_LDIV_OFFSET;
555 
556 	return jz_clk_pll_half_get_rate(clk->parent) / (div + 1);
557 }
558 
559 static const struct clk_ops jz_clk_ops_ld = {
560 	.set_rate = jz_clk_ldclk_set_rate,
561 	.get_rate = jz_clk_ldclk_get_rate,
562 	.round_rate = jz_clk_ldclk_round_rate,
563 	.enable = jz_clk_enable_gating,
564 	.disable = jz_clk_disable_gating,
565 	.is_enabled = jz_clk_is_enabled_gating,
566 };
567 
568 static struct clk jz_clk_ld = {
569 	.name = "lcd",
570 	.gate_bit = JZ_CLOCK_GATE_LCD,
571 	.parent = &jz_clk_pll_half,
572 	.ops = &jz_clk_ops_ld,
573 };
574 
575 static const struct clk_ops jz_clk_i2s_ops = {
576 	.set_rate = jz_clk_divided_set_rate,
577 	.get_rate = jz_clk_divided_get_rate,
578 	.enable = jz_clk_enable_gating,
579 	.disable = jz_clk_disable_gating,
580 	.is_enabled = jz_clk_is_enabled_gating,
581 	.set_parent = jz_clk_i2s_set_parent,
582 };
583 
584 static const struct clk_ops jz_clk_spi_ops = {
585 	.set_rate = jz_clk_divided_set_rate,
586 	.get_rate = jz_clk_divided_get_rate,
587 	.enable = jz_clk_enable_gating,
588 	.disable = jz_clk_disable_gating,
589 	.is_enabled = jz_clk_is_enabled_gating,
590 	.set_parent = jz_clk_spi_set_parent,
591 };
592 
593 static const struct clk_ops jz_clk_divided_ops = {
594 	.set_rate = jz_clk_divided_set_rate,
595 	.get_rate = jz_clk_divided_get_rate,
596 	.enable = jz_clk_enable_gating,
597 	.disable = jz_clk_disable_gating,
598 	.is_enabled = jz_clk_is_enabled_gating,
599 };
600 
601 static struct divided_clk jz4740_clock_divided_clks[] = {
602 	[0] = {
603 		.clk = {
604 			.name = "i2s",
605 			.parent = &jz_clk_ext.clk,
606 			.gate_bit = JZ_CLOCK_GATE_I2S,
607 			.ops = &jz_clk_i2s_ops,
608 		},
609 		.reg = JZ_REG_CLOCK_I2S,
610 		.mask = JZ_CLOCK_I2S_DIV_MASK,
611 	},
612 	[1] = {
613 		.clk = {
614 			.name = "spi",
615 			.parent = &jz_clk_ext.clk,
616 			.gate_bit = JZ_CLOCK_GATE_SPI,
617 			.ops = &jz_clk_spi_ops,
618 		},
619 		.reg = JZ_REG_CLOCK_SPI,
620 		.mask = JZ_CLOCK_SPI_DIV_MASK,
621 	},
622 	[2] = {
623 		.clk = {
624 			.name = "lcd_pclk",
625 			.parent = &jz_clk_pll_half,
626 			.gate_bit = JZ4740_CLK_NOT_GATED,
627 			.ops = &jz_clk_divided_ops,
628 		},
629 		.reg = JZ_REG_CLOCK_LCD,
630 		.mask = JZ_CLOCK_LCD_DIV_MASK,
631 	},
632 	[3] = {
633 		.clk = {
634 			.name = "mmc",
635 			.parent = &jz_clk_pll_half,
636 			.gate_bit = JZ_CLOCK_GATE_MMC,
637 			.ops = &jz_clk_divided_ops,
638 		},
639 		.reg = JZ_REG_CLOCK_MMC,
640 		.mask = JZ_CLOCK_MMC_DIV_MASK,
641 	},
642 	[4] = {
643 		.clk = {
644 			.name = "uhc",
645 			.parent = &jz_clk_pll_half,
646 			.gate_bit = JZ_CLOCK_GATE_UHC,
647 			.ops = &jz_clk_divided_ops,
648 		},
649 		.reg = JZ_REG_CLOCK_UHC,
650 		.mask = JZ_CLOCK_UHC_DIV_MASK,
651 	},
652 };
653 
654 static const struct clk_ops jz_clk_udc_ops = {
655 	.set_parent = jz_clk_udc_set_parent,
656 	.set_rate = jz_clk_udc_set_rate,
657 	.get_rate = jz_clk_udc_get_rate,
658 	.enable = jz_clk_udc_enable,
659 	.disable = jz_clk_udc_disable,
660 	.is_enabled = jz_clk_udc_is_enabled,
661 };
662 
663 static const struct clk_ops jz_clk_simple_ops = {
664 	.enable = jz_clk_enable_gating,
665 	.disable = jz_clk_disable_gating,
666 	.is_enabled = jz_clk_is_enabled_gating,
667 };
668 
669 static struct clk jz4740_clock_simple_clks[] = {
670 	[0] = {
671 		.name = "udc",
672 		.parent = &jz_clk_ext.clk,
673 		.ops = &jz_clk_udc_ops,
674 	},
675 	[1] = {
676 		.name = "uart0",
677 		.parent = &jz_clk_ext.clk,
678 		.gate_bit = JZ_CLOCK_GATE_UART0,
679 		.ops = &jz_clk_simple_ops,
680 	},
681 	[2] = {
682 		.name = "uart1",
683 		.parent = &jz_clk_ext.clk,
684 		.gate_bit = JZ_CLOCK_GATE_UART1,
685 		.ops = &jz_clk_simple_ops,
686 	},
687 	[3] = {
688 		.name = "dma",
689 		.parent = &jz_clk_high_speed_peripheral.clk,
690 		.gate_bit = JZ_CLOCK_GATE_UART0,
691 		.ops = &jz_clk_simple_ops,
692 	},
693 	[4] = {
694 		.name = "ipu",
695 		.parent = &jz_clk_high_speed_peripheral.clk,
696 		.gate_bit = JZ_CLOCK_GATE_IPU,
697 		.ops = &jz_clk_simple_ops,
698 	},
699 	[5] = {
700 		.name = "adc",
701 		.parent = &jz_clk_ext.clk,
702 		.gate_bit = JZ_CLOCK_GATE_ADC,
703 		.ops = &jz_clk_simple_ops,
704 	},
705 	[6] = {
706 		.name = "i2c",
707 		.parent = &jz_clk_ext.clk,
708 		.gate_bit = JZ_CLOCK_GATE_I2C,
709 		.ops = &jz_clk_simple_ops,
710 	},
711 	[7] = {
712 		.name = "aic",
713 		.parent = &jz_clk_ext.clk,
714 		.gate_bit = JZ_CLOCK_GATE_AIC,
715 		.ops = &jz_clk_simple_ops,
716 	},
717 };
718 
719 static struct static_clk jz_clk_rtc = {
720 	.clk = {
721 		.name = "rtc",
722 		.gate_bit = JZ_CLOCK_GATE_RTC,
723 		.ops = &jz_clk_static_ops,
724 	},
725 	.rate = 32768,
726 };
727 
clk_enable(struct clk * clk)728 int clk_enable(struct clk *clk)
729 {
730 	if (!clk->ops->enable)
731 		return -EINVAL;
732 
733 	return clk->ops->enable(clk);
734 }
735 EXPORT_SYMBOL_GPL(clk_enable);
736 
clk_disable(struct clk * clk)737 void clk_disable(struct clk *clk)
738 {
739 	if (clk->ops->disable)
740 		clk->ops->disable(clk);
741 }
742 EXPORT_SYMBOL_GPL(clk_disable);
743 
clk_is_enabled(struct clk * clk)744 int clk_is_enabled(struct clk *clk)
745 {
746 	if (clk->ops->is_enabled)
747 		return clk->ops->is_enabled(clk);
748 
749 	return 1;
750 }
751 
clk_get_rate(struct clk * clk)752 unsigned long clk_get_rate(struct clk *clk)
753 {
754 	if (clk->ops->get_rate)
755 		return clk->ops->get_rate(clk);
756 	if (clk->parent)
757 		return clk_get_rate(clk->parent);
758 
759 	return -EINVAL;
760 }
761 EXPORT_SYMBOL_GPL(clk_get_rate);
762 
clk_set_rate(struct clk * clk,unsigned long rate)763 int clk_set_rate(struct clk *clk, unsigned long rate)
764 {
765 	if (!clk->ops->set_rate)
766 		return -EINVAL;
767 	return clk->ops->set_rate(clk, rate);
768 }
769 EXPORT_SYMBOL_GPL(clk_set_rate);
770 
clk_round_rate(struct clk * clk,unsigned long rate)771 long clk_round_rate(struct clk *clk, unsigned long rate)
772 {
773 	if (clk->ops->round_rate)
774 		return clk->ops->round_rate(clk, rate);
775 
776 	return -EINVAL;
777 }
778 EXPORT_SYMBOL_GPL(clk_round_rate);
779 
clk_set_parent(struct clk * clk,struct clk * parent)780 int clk_set_parent(struct clk *clk, struct clk *parent)
781 {
782 	int ret;
783 	int enabled;
784 
785 	if (!clk->ops->set_parent)
786 		return -EINVAL;
787 
788 	enabled = clk_is_enabled(clk);
789 	if (enabled)
790 		clk_disable(clk);
791 	ret = clk->ops->set_parent(clk, parent);
792 	if (enabled)
793 		clk_enable(clk);
794 
795 	jz4740_clock_debugfs_update_parent(clk);
796 
797 	return ret;
798 }
799 EXPORT_SYMBOL_GPL(clk_set_parent);
800 
clk_get(struct device * dev,const char * name)801 struct clk *clk_get(struct device *dev, const char *name)
802 {
803 	struct clk *clk;
804 
805 	list_for_each_entry(clk, &jz_clocks, list) {
806 		if (strcmp(clk->name, name) == 0)
807 			return clk;
808 	}
809 	return ERR_PTR(-ENXIO);
810 }
811 EXPORT_SYMBOL_GPL(clk_get);
812 
clk_put(struct clk * clk)813 void clk_put(struct clk *clk)
814 {
815 }
816 EXPORT_SYMBOL_GPL(clk_put);
817 
clk_add(struct clk * clk)818 static inline void clk_add(struct clk *clk)
819 {
820 	list_add_tail(&clk->list, &jz_clocks);
821 
822 	jz4740_clock_debugfs_add_clk(clk);
823 }
824 
clk_register_clks(void)825 static void clk_register_clks(void)
826 {
827 	size_t i;
828 
829 	clk_add(&jz_clk_ext.clk);
830 	clk_add(&jz_clk_pll);
831 	clk_add(&jz_clk_pll_half);
832 	clk_add(&jz_clk_cpu.clk);
833 	clk_add(&jz_clk_high_speed_peripheral.clk);
834 	clk_add(&jz_clk_low_speed_peripheral.clk);
835 	clk_add(&jz_clk_ko);
836 	clk_add(&jz_clk_ld);
837 	clk_add(&jz_clk_rtc.clk);
838 
839 	for (i = 0; i < ARRAY_SIZE(jz4740_clock_divided_clks); ++i)
840 		clk_add(&jz4740_clock_divided_clks[i].clk);
841 
842 	for (i = 0; i < ARRAY_SIZE(jz4740_clock_simple_clks); ++i)
843 		clk_add(&jz4740_clock_simple_clks[i]);
844 }
845 
jz4740_clock_set_wait_mode(enum jz4740_wait_mode mode)846 void jz4740_clock_set_wait_mode(enum jz4740_wait_mode mode)
847 {
848 	switch (mode) {
849 	case JZ4740_WAIT_MODE_IDLE:
850 		jz_clk_reg_clear_bits(JZ_REG_CLOCK_LOW_POWER, JZ_CLOCK_LOW_POWER_MODE_SLEEP);
851 		break;
852 	case JZ4740_WAIT_MODE_SLEEP:
853 		jz_clk_reg_set_bits(JZ_REG_CLOCK_LOW_POWER, JZ_CLOCK_LOW_POWER_MODE_SLEEP);
854 		break;
855 	}
856 }
857 
jz4740_clock_udc_disable_auto_suspend(void)858 void jz4740_clock_udc_disable_auto_suspend(void)
859 {
860 	jz_clk_reg_clear_bits(JZ_REG_CLOCK_GATE, JZ_CLOCK_GATE_UDC);
861 }
862 EXPORT_SYMBOL_GPL(jz4740_clock_udc_disable_auto_suspend);
863 
jz4740_clock_udc_enable_auto_suspend(void)864 void jz4740_clock_udc_enable_auto_suspend(void)
865 {
866 	jz_clk_reg_set_bits(JZ_REG_CLOCK_GATE, JZ_CLOCK_GATE_UDC);
867 }
868 EXPORT_SYMBOL_GPL(jz4740_clock_udc_enable_auto_suspend);
869 
jz4740_clock_suspend(void)870 void jz4740_clock_suspend(void)
871 {
872 	jz_clk_reg_set_bits(JZ_REG_CLOCK_GATE,
873 		JZ_CLOCK_GATE_TCU | JZ_CLOCK_GATE_DMAC | JZ_CLOCK_GATE_UART0);
874 
875 	jz_clk_reg_clear_bits(JZ_REG_CLOCK_PLL, JZ_CLOCK_PLL_ENABLED);
876 }
877 
jz4740_clock_resume(void)878 void jz4740_clock_resume(void)
879 {
880 	uint32_t pll;
881 
882 	jz_clk_reg_set_bits(JZ_REG_CLOCK_PLL, JZ_CLOCK_PLL_ENABLED);
883 
884 	do {
885 		pll = jz_clk_reg_read(JZ_REG_CLOCK_PLL);
886 	} while (!(pll & JZ_CLOCK_PLL_STABLE));
887 
888 	jz_clk_reg_clear_bits(JZ_REG_CLOCK_GATE,
889 		JZ_CLOCK_GATE_TCU | JZ_CLOCK_GATE_DMAC | JZ_CLOCK_GATE_UART0);
890 }
891 
jz4740_clock_init(void)892 static int jz4740_clock_init(void)
893 {
894 	uint32_t val;
895 
896 	jz_clock_base = ioremap(JZ4740_CPM_BASE_ADDR, 0x100);
897 	if (!jz_clock_base)
898 		return -EBUSY;
899 
900 	spin_lock_init(&jz_clock_lock);
901 
902 	jz_clk_ext.rate = jz4740_clock_bdata.ext_rate;
903 	jz_clk_rtc.rate = jz4740_clock_bdata.rtc_rate;
904 
905 	val = jz_clk_reg_read(JZ_REG_CLOCK_SPI);
906 
907 	if (val & JZ_CLOCK_SPI_SRC_PLL)
908 		jz4740_clock_divided_clks[1].clk.parent = &jz_clk_pll_half;
909 
910 	val = jz_clk_reg_read(JZ_REG_CLOCK_CTRL);
911 
912 	if (val & JZ_CLOCK_CTRL_I2S_SRC_PLL)
913 		jz4740_clock_divided_clks[0].clk.parent = &jz_clk_pll_half;
914 
915 	if (val & JZ_CLOCK_CTRL_UDC_SRC_PLL)
916 		jz4740_clock_simple_clks[0].parent = &jz_clk_pll_half;
917 
918 	jz4740_clock_debugfs_init();
919 
920 	clk_register_clks();
921 
922 	return 0;
923 }
924 arch_initcall(jz4740_clock_init);
925