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