2 * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
3 * JZ4740 SoC clock support
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.
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.
16 #include <linux/kernel.h>
17 #include <linux/errno.h>
18 #include <linux/clk.h>
19 #include <linux/spinlock.h>
21 #include <linux/module.h>
22 #include <linux/list.h>
23 #include <linux/err.h>
25 #include <asm/mach-jz4740/clock.h>
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
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
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)
69 #define JZ_CLOCK_I2S_DIV_MASK 0x01ff
71 #define JZ_CLOCK_LCD_DIV_MASK 0x01ff
73 #define JZ_CLOCK_MMC_DIV_MASK 0x001f
75 #define JZ_CLOCK_UHC_DIV_MASK 0x000f
77 #define JZ_CLOCK_SPI_SRC_PLL BIT(31)
78 #define JZ_CLOCK_SPI_DIV_MASK 0x000f
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
91 #define JZ_CLOCK_LOW_POWER_MODE_DOZE BIT(2)
92 #define JZ_CLOCK_LOW_POWER_MODE_SLEEP BIT(0)
94 #define JZ_CLOCK_SLEEP_CTRL_SUSPEND_UHC BIT(7)
95 #define JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC BIT(6)
97 static void __iomem
*jz_clock_base
;
98 static spinlock_t jz_clock_lock
;
99 static LIST_HEAD(jz_clocks
);
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
);
108 int (*set_parent
)(struct clk
* clk
, struct clk
*parent
);
117 const struct clk_ops
*ops
;
119 struct list_head list
;
138 static uint32_t jz_clk_reg_read(int reg
)
140 return readl(jz_clock_base
+ reg
);
143 static void jz_clk_reg_write_mask(int reg
, uint32_t val
, uint32_t mask
)
147 spin_lock(&jz_clock_lock
);
148 val2
= readl(jz_clock_base
+ reg
);
151 writel(val2
, jz_clock_base
+ reg
);
152 spin_unlock(&jz_clock_lock
);
155 static void jz_clk_reg_set_bits(int reg
, uint32_t mask
)
159 spin_lock(&jz_clock_lock
);
160 val
= readl(jz_clock_base
+ reg
);
162 writel(val
, jz_clock_base
+ reg
);
163 spin_unlock(&jz_clock_lock
);
166 static void jz_clk_reg_clear_bits(int reg
, uint32_t mask
)
170 spin_lock(&jz_clock_lock
);
171 val
= readl(jz_clock_base
+ reg
);
173 writel(val
, jz_clock_base
+ reg
);
174 spin_unlock(&jz_clock_lock
);
177 static int jz_clk_enable_gating(struct clk
*clk
)
179 jz_clk_reg_clear_bits(JZ_REG_CLOCK_GATE
, clk
->gate_bit
);
183 static int jz_clk_disable_gating(struct clk
*clk
)
185 jz_clk_reg_set_bits(JZ_REG_CLOCK_GATE
, clk
->gate_bit
);
189 static unsigned long jz_clk_static_get_rate(struct clk
*clk
)
191 return ((struct static_clk
*)clk
)->rate
;
194 static int jz_clk_ko_enable(struct clk
* clk
)
196 jz_clk_reg_set_bits(JZ_REG_CLOCK_CTRL
, JZ_CLOCK_CTRL_KO_ENABLE
);
200 static int jz_clk_ko_disable(struct clk
* clk
)
202 jz_clk_reg_clear_bits(JZ_REG_CLOCK_CTRL
, JZ_CLOCK_CTRL_KO_ENABLE
);
207 static const int pllno
[] = {1, 2, 2, 4};
209 static unsigned long jz_clk_pll_get_rate(struct clk
*clk
)
216 val
= jz_clk_reg_read(JZ_REG_CLOCK_PLL
);
218 if (val
& JZ_CLOCK_PLL_BYPASS
)
219 return clk_get_rate(clk
->parent
);
221 m
= ((val
>> 23) & 0x1ff) + 2;
222 n
= ((val
>> 18) & 0x1f) + 2;
223 od
= (val
>> 16) & 0x3;
225 return clk_get_rate(clk
->parent
) * (m
/ n
) / pllno
[od
];
228 static unsigned long jz_clk_pll_half_get_rate(struct clk
*clk
)
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;
238 static const int jz_clk_main_divs
[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32};
240 static unsigned long jz_clk_main_round_rate(struct clk
*clk
, unsigned long rate
)
242 unsigned long parent_rate
= jz_clk_pll_get_rate(clk
->parent
);
245 div
= parent_rate
/ rate
;
247 return parent_rate
/ 32;
251 div
&= (0x3 << (ffs(div
) - 1));
253 return parent_rate
/ div
;
256 static unsigned long jz_clk_main_get_rate(struct clk
*clk
) {
257 struct main_clk
*mclk
= (struct main_clk
*)clk
;
260 div
= jz_clk_reg_read(JZ_REG_CLOCK_CTRL
);
262 div
>>= mclk
->div_offset
;
265 if (div
>= ARRAY_SIZE(jz_clk_main_divs
))
266 div
= ARRAY_SIZE(jz_clk_main_divs
) - 1;
268 return jz_clk_pll_get_rate(clk
->parent
) / jz_clk_main_divs
[div
];
271 static int jz_clk_main_set_rate(struct clk
*clk
, unsigned long rate
)
273 struct main_clk
*mclk
= (struct main_clk
*)clk
;
276 unsigned long parent_rate
= jz_clk_pll_get_rate(clk
->parent
);
278 rate
= jz_clk_main_round_rate(clk
, rate
);
280 div
= parent_rate
/ rate
;
282 i
= (ffs(div
) - 1) << 1;
283 if (i
> 0 && !(div
& BIT(i
-1)))
286 jz_clk_reg_write_mask(JZ_REG_CLOCK_CTRL
, i
<< mclk
->div_offset
,
287 0xf << mclk
->div_offset
);
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
,
298 static struct static_clk jz_clk_ext
= {
301 .gate_bit
= (uint32_t)-1,
302 .ops
= &jz_clk_static_ops
,
306 static struct clk_ops jz_clk_pll_ops
= {
307 .get_rate
= jz_clk_static_get_rate
,
310 static struct clk jz_clk_pll
= {
312 .parent
= &jz_clk_ext
.clk
,
313 .ops
= &jz_clk_pll_ops
,
316 static struct clk_ops jz_clk_pll_half_ops
= {
317 .get_rate
= jz_clk_pll_half_get_rate
,
320 static struct clk jz_clk_pll_half
= {
322 .parent
= &jz_clk_pll
,
323 .ops
= &jz_clk_pll_half_ops
,
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
,
332 static struct main_clk jz_clk_cpu
= {
335 .parent
= &jz_clk_pll
,
336 .ops
= &jz_clk_main_ops
,
338 .div_offset
= JZ_CLOCK_CTRL_CDIV_OFFSET
,
341 static struct main_clk jz_clk_memory
= {
344 .parent
= &jz_clk_pll
,
345 .ops
= &jz_clk_main_ops
,
347 .div_offset
= JZ_CLOCK_CTRL_MDIV_OFFSET
,
350 static struct main_clk jz_clk_high_speed_peripheral
= {
353 .parent
= &jz_clk_pll
,
354 .ops
= &jz_clk_main_ops
,
356 .div_offset
= JZ_CLOCK_CTRL_HDIV_OFFSET
,
360 static struct main_clk jz_clk_low_speed_peripheral
= {
363 .parent
= &jz_clk_pll
,
364 .ops
= &jz_clk_main_ops
,
366 .div_offset
= JZ_CLOCK_CTRL_PDIV_OFFSET
,
369 static const struct clk_ops jz_clk_ko_ops
= {
370 .enable
= jz_clk_ko_enable
,
371 .disable
= jz_clk_ko_disable
,
374 static struct clk jz_clk_ko
= {
376 .parent
= &jz_clk_memory
.clk
,
377 .ops
= &jz_clk_ko_ops
,
380 static int jz_clk_spi_set_parent(struct clk
*clk
, struct clk
*parent
)
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
);
389 clk
->parent
= parent
;
394 static int jz_clk_i2s_set_parent(struct clk
*clk
, struct clk
*parent
)
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
);
403 clk
->parent
= parent
;
408 static int jz_clk_udc_disable(struct clk
*clk
)
410 jz_clk_reg_clear_bits(JZ_REG_CLOCK_SLEEP_CTRL
,
411 JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC
);
416 static int jz_clk_udc_enable(struct clk
*clk
)
418 jz_clk_reg_set_bits(JZ_REG_CLOCK_SLEEP_CTRL
,
419 JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC
);
424 static int jz_clk_udc_set_parent(struct clk
*clk
, struct clk
*parent
)
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
);
433 clk
->parent
= parent
;
438 static int jz_clk_udc_set_rate(struct clk
*clk
, unsigned long rate
)
442 if (clk
->parent
== &jz_clk_ext
.clk
)
445 div
= clk_get_rate(clk
->parent
) / rate
- 1;
452 jz_clk_reg_write_mask(JZ_REG_CLOCK_CTRL
, div
<< JZ_CLOCK_CTRL_UDIV_OFFSET
,
453 JZ_CLOCK_CTRL_UDIV_MASK
);
457 static unsigned long jz_clk_udc_get_rate(struct clk
*clk
)
461 if (clk
->parent
== &jz_clk_ext
.clk
)
462 return clk_get_rate(clk
->parent
);
464 div
= (jz_clk_reg_read(JZ_REG_CLOCK_CTRL
) & JZ_CLOCK_CTRL_UDIV_MASK
);
465 div
>>= JZ_CLOCK_CTRL_UDIV_OFFSET
;
468 return clk_get_rate(clk
->parent
) / div
;
471 static unsigned long jz_clk_divided_get_rate(struct clk
*clk
)
473 struct divided_clk
*dclk
= (struct divided_clk
*)clk
;
476 if (clk
->parent
== &jz_clk_ext
.clk
)
477 return clk_get_rate(clk
->parent
);
479 div
= (jz_clk_reg_read(dclk
->reg
) & dclk
->mask
) + 1;
481 return clk_get_rate(clk
->parent
) / div
;
484 static int jz_clk_divided_set_rate(struct clk
*clk
, unsigned long rate
)
486 struct divided_clk
*dclk
= (struct divided_clk
*)clk
;
489 if (clk
->parent
== &jz_clk_ext
.clk
)
492 div
= clk_get_rate(clk
->parent
) / rate
- 1;
496 else if(div
> dclk
->mask
)
499 jz_clk_reg_write_mask(dclk
->reg
, div
, dclk
->mask
);
504 static unsigned long jz_clk_ldclk_round_rate(struct clk
*clk
, unsigned long rate
)
507 unsigned long parent_rate
= jz_clk_pll_half_get_rate(clk
->parent
);
509 if (rate
> 150000000)
512 div
= parent_rate
/ rate
;
518 return parent_rate
/ div
;
521 static int jz_clk_ldclk_set_rate(struct clk
*clk
, unsigned long rate
)
525 if (rate
> 150000000)
528 div
= jz_clk_pll_half_get_rate(clk
->parent
) / rate
- 1;
534 jz_clk_reg_write_mask(JZ_REG_CLOCK_CTRL
, div
<< JZ_CLOCK_CTRL_LDIV_OFFSET
,
535 JZ_CLOCK_CTRL_LDIV_MASK
);
540 static unsigned long jz_clk_ldclk_get_rate(struct clk
*clk
)
544 div
= jz_clk_reg_read(JZ_REG_CLOCK_CTRL
) & JZ_CLOCK_CTRL_LDIV_MASK
;
545 div
>>= JZ_CLOCK_CTRL_LDIV_OFFSET
;
547 return jz_clk_pll_half_get_rate(clk
->parent
) / (div
+ 1);
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
,
556 static struct clk jz_clk_ld
= {
558 .parent
= &jz_clk_pll_half
,
559 .ops
= &jz_clk_ops_ld
,
562 static struct divided_clk jz_clk_lp
= {
565 .parent
= &jz_clk_pll_half
,
567 .reg
= JZ_REG_CLOCK_LCD
,
568 .mask
= JZ_CLOCK_LCD_DIV_MASK
,
571 static struct clk jz_clk_cim_mclk
= {
573 .parent
= &jz_clk_high_speed_peripheral
.clk
,
576 static struct static_clk jz_clk_cim_pclk
= {
579 .gate_bit
= JZ_CLOCK_GATE_CIM
,
580 .ops
= &jz_clk_static_ops
,
584 static const struct clk_ops jz_clk_i2s_ops
=
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
,
593 static const struct clk_ops jz_clk_spi_ops
=
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
,
602 static const struct clk_ops jz_clk_divided_ops
=
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
,
610 static struct divided_clk jz4740_clock_divided_clks
[] = {
614 .parent
= &jz_clk_ext
.clk
,
615 .gate_bit
= JZ_CLOCK_GATE_AIC
,
616 .ops
= &jz_clk_i2s_ops
,
618 .reg
= JZ_REG_CLOCK_I2S
,
619 .mask
= JZ_CLOCK_I2S_DIV_MASK
,
624 .parent
= &jz_clk_ext
.clk
,
625 .gate_bit
= JZ_CLOCK_GATE_SPI
,
626 .ops
= &jz_clk_spi_ops
,
628 .reg
= JZ_REG_CLOCK_SPI
,
629 .mask
= JZ_CLOCK_SPI_DIV_MASK
,
634 .parent
= &jz_clk_pll_half
,
635 .gate_bit
= JZ_CLOCK_GATE_MMC
,
636 .ops
= &jz_clk_divided_ops
,
638 .reg
= JZ_REG_CLOCK_MMC
,
639 .mask
= JZ_CLOCK_MMC_DIV_MASK
,
644 .parent
= &jz_clk_pll_half
,
645 .gate_bit
= JZ_CLOCK_GATE_UHC
,
646 .ops
= &jz_clk_divided_ops
,
648 .reg
= JZ_REG_CLOCK_UHC
,
649 .mask
= JZ_CLOCK_UHC_DIV_MASK
,
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
,
661 static const struct clk_ops jz_clk_simple_ops
= {
662 .enable
= jz_clk_enable_gating
,
663 .disable
= jz_clk_disable_gating
,
666 static struct clk jz4740_clock_simple_clks
[] = {
669 .parent
= &jz_clk_ext
.clk
,
670 .ops
= &jz_clk_udc_ops
,
674 .parent
= &jz_clk_ext
.clk
,
675 .gate_bit
= JZ_CLOCK_GATE_UART0
,
676 .ops
= &jz_clk_simple_ops
,
680 .parent
= &jz_clk_ext
.clk
,
681 .gate_bit
= JZ_CLOCK_GATE_UART1
,
682 .ops
= &jz_clk_simple_ops
,
686 .parent
= &jz_clk_high_speed_peripheral
.clk
,
687 .gate_bit
= JZ_CLOCK_GATE_UART0
,
688 .ops
= &jz_clk_simple_ops
,
692 .parent
= &jz_clk_high_speed_peripheral
.clk
,
693 .gate_bit
= JZ_CLOCK_GATE_IPU
,
694 .ops
= &jz_clk_simple_ops
,
698 .parent
= &jz_clk_ext
.clk
,
699 .gate_bit
= JZ_CLOCK_GATE_ADC
,
700 .ops
= &jz_clk_simple_ops
,
704 .parent
= &jz_clk_ext
.clk
,
705 .gate_bit
= JZ_CLOCK_GATE_I2C
,
706 .ops
= &jz_clk_simple_ops
,
710 static struct static_clk jz_clk_rtc
= {
713 .gate_bit
= JZ_CLOCK_GATE_RTC
,
714 .ops
= &jz_clk_static_ops
,
719 int clk_enable(struct clk
*clk
)
721 if (!clk
->ops
->enable
)
724 return clk
->ops
->enable(clk
);
726 EXPORT_SYMBOL_GPL(clk_enable
);
728 void clk_disable(struct clk
*clk
)
730 if (clk
->ops
->disable
)
731 clk
->ops
->disable(clk
);
733 EXPORT_SYMBOL_GPL(clk_disable
);
735 unsigned long clk_get_rate(struct clk
*clk
)
737 if (clk
->ops
->get_rate
)
738 return clk
->ops
->get_rate(clk
);
740 return clk_get_rate(clk
->parent
);
744 EXPORT_SYMBOL_GPL(clk_get_rate
);
746 int clk_set_rate(struct clk
*clk
, unsigned long rate
)
748 if (!clk
->ops
->set_rate
)
750 return clk
->ops
->set_rate(clk
, rate
);
752 EXPORT_SYMBOL_GPL(clk_set_rate
);
754 long clk_round_rate(struct clk
*clk
, unsigned long rate
)
756 if (clk
->ops
->round_rate
)
757 return clk
->ops
->round_rate(clk
, rate
);
761 EXPORT_SYMBOL_GPL(clk_round_rate
);
763 int clk_set_parent(struct clk
*clk
, struct clk
*parent
)
767 if (!clk
->ops
->set_parent
)
771 ret
= clk
->ops
->set_parent(clk
, parent
);
776 EXPORT_SYMBOL_GPL(clk_set_parent
);
778 struct clk
*clk_get(struct device
*dev
, const char *name
)
782 list_for_each_entry(clk
, &jz_clocks
, list
) {
783 if (strcmp(clk
->name
, name
) == 0)
786 return ERR_PTR(-ENOENT
);
788 EXPORT_SYMBOL_GPL(clk_get
);
790 void clk_put(struct clk
*clk
)
793 EXPORT_SYMBOL_GPL(clk_put
);
795 inline static void clk_add(struct clk
*clk
)
797 list_add_tail(&clk
->list
, &jz_clocks
);
800 static void clk_register_clks(void)
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
);
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
);
817 for (i
= 0; i
< ARRAY_SIZE(jz4740_clock_divided_clks
); ++i
)
818 clk_add(&jz4740_clock_divided_clks
[i
].clk
);
820 for (i
= 0; i
< ARRAY_SIZE(jz4740_clock_simple_clks
); ++i
)
821 clk_add(&jz4740_clock_simple_clks
[i
]);
824 void jz4740_clock_set_wait_mode(enum jz4740_wait_mode mode
)
827 case JZ4740_WAIT_MODE_IDLE
:
828 jz_clk_reg_clear_bits(JZ_REG_CLOCK_LOW_POWER
, JZ_CLOCK_LOW_POWER_MODE_SLEEP
);
830 case JZ4740_WAIT_MODE_SLEEP
:
831 jz_clk_reg_set_bits(JZ_REG_CLOCK_LOW_POWER
, JZ_CLOCK_LOW_POWER_MODE_SLEEP
);
836 void jz4740_clock_udc_disable_auto_suspend(void)
838 jz_clk_reg_clear_bits(JZ_REG_CLOCK_GATE
, JZ_CLOCK_GATE_UDC
);
840 EXPORT_SYMBOL_GPL(jz4740_clock_udc_disable_auto_suspend
);
842 void jz4740_clock_udc_enable_auto_suspend(void)
844 jz_clk_reg_set_bits(JZ_REG_CLOCK_GATE
, JZ_CLOCK_GATE_UDC
);
846 EXPORT_SYMBOL_GPL(jz4740_clock_udc_enable_auto_suspend
);
848 int jz_init_clocks(unsigned long ext_rate
)
852 jz_clock_base
= ioremap(CPHYSADDR(CPM_BASE
), 0x100);
856 spin_lock_init(&jz_clock_lock
);
858 jz_clk_ext
.rate
= ext_rate
;
860 val
= jz_clk_reg_read(JZ_REG_CLOCK_SPI
);
862 if (val
& JZ_CLOCK_SPI_SRC_PLL
)
863 jz4740_clock_divided_clks
[1].clk
.parent
= &jz_clk_pll_half
;
865 val
= jz_clk_reg_read(JZ_REG_CLOCK_CTRL
);
867 if (val
& JZ_CLOCK_CTRL_I2S_SRC_PLL
)
868 jz4740_clock_divided_clks
[0].clk
.parent
= &jz_clk_pll_half
;
870 if (val
& JZ_CLOCK_CTRL_UDC_SRC_PLL
)
871 jz4740_clock_simple_clks
[0].parent
= &jz_clk_pll_half
;
877 EXPORT_SYMBOL_GPL(jz_init_clocks
);