Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
clock.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2010, Lars-Peter Clausen <[email protected]>
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;
107 };
108 
109 struct divided_clk {
110  struct clk clk;
113 };
114 
115 struct static_clk {
116  struct clk clk;
117  unsigned long rate;
118 };
119 
120 static uint32_t jz_clk_reg_read(int reg)
121 {
122  return readl(jz_clock_base + reg);
123 }
124 
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 
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 
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 
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 
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 
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 
185 static unsigned long jz_clk_static_get_rate(struct clk *clk)
186 {
187  return ((struct static_clk *)clk)->rate;
188 }
189 
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 
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 
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 
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 
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 {
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 
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 
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 
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 
411 static int jz_clk_udc_enable(struct clk *clk)
412 {
413  jz_clk_reg_set_bits(JZ_REG_CLOCK_SLEEP_CTRL,
415 
416  return 0;
417 }
418 
419 static int jz_clk_udc_disable(struct clk *clk)
420 {
421  jz_clk_reg_clear_bits(JZ_REG_CLOCK_SLEEP_CTRL,
423 
424  return 0;
425 }
426 
427 static int jz_clk_udc_is_enabled(struct clk *clk)
428 {
429  return !!(jz_clk_reg_read(JZ_REG_CLOCK_SLEEP_CTRL) &
431 }
432 
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 
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,
463  return 0;
464 }
465 
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);
475  div += 1;
476 
477  return clk_get_rate(clk->parent) / div;
478 }
479 
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 
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 
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 
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,
545 
546  return 0;
547 }
548 
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;
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,
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,
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,
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 
728 int clk_enable(struct clk *clk)
729 {
730  if (!clk->ops->enable)
731  return -EINVAL;
732 
733  return clk->ops->enable(clk);
734 }
736 
737 void clk_disable(struct clk *clk)
738 {
739  if (clk->ops->disable)
740  clk->ops->disable(clk);
741 }
743 
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 
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 }
762 
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 }
770 
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 }
779 
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 
796 
797  return ret;
798 }
800 
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 }
812 
813 void clk_put(struct clk *clk)
814 {
815 }
817 
818 static inline void clk_add(struct clk *clk)
819 {
820  list_add_tail(&clk->list, &jz_clocks);
821 
823 }
824 
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 
847 {
848  switch (mode) {
851  break;
854  break;
855  }
856 }
857 
859 {
860  jz_clk_reg_clear_bits(JZ_REG_CLOCK_GATE, JZ_CLOCK_GATE_UDC);
861 }
863 
865 {
866  jz_clk_reg_set_bits(JZ_REG_CLOCK_GATE, JZ_CLOCK_GATE_UDC);
867 }
869 
871 {
872  jz_clk_reg_set_bits(JZ_REG_CLOCK_GATE,
874 
875  jz_clk_reg_clear_bits(JZ_REG_CLOCK_PLL, JZ_CLOCK_PLL_ENABLED);
876 }
877 
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,
890 }
891 
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 
919 
920  clk_register_clks();
921 
922  return 0;
923 }
924 arch_initcall(jz4740_clock_init);