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