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>
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
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
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)
70 #define JZ_CLOCK_I2S_DIV_MASK 0x01ff
72 #define JZ_CLOCK_LCD_DIV_MASK 0x01ff
74 #define JZ_CLOCK_MMC_DIV_MASK 0x001f
76 #define JZ_CLOCK_UHC_DIV_MASK 0x000f
78 #define JZ_CLOCK_SPI_SRC_PLL BIT(31)
79 #define JZ_CLOCK_SPI_DIV_MASK 0x000f
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
92 #define JZ_CLOCK_LOW_POWER_MODE_DOZE BIT(2)
93 #define JZ_CLOCK_LOW_POWER_MODE_SLEEP BIT(0)
95 #define JZ_CLOCK_SLEEP_CTRL_SUSPEND_UHC BIT(7)
96 #define JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC BIT(6)
98 static void __iomem
*jz_clock_base
;
99 static spinlock_t jz_clock_lock
;
100 static LIST_HEAD(jz_clocks
);
118 static uint32_t jz_clk_reg_read(int reg
)
120 return readl(jz_clock_base
+ reg
);
123 static void jz_clk_reg_write_mask(int reg
, uint32_t val
, uint32_t mask
)
127 spin_lock(&jz_clock_lock
);
128 val2
= readl(jz_clock_base
+ reg
);
131 writel(val2
, jz_clock_base
+ reg
);
132 spin_unlock(&jz_clock_lock
);
135 static void jz_clk_reg_set_bits(int reg
, uint32_t mask
)
139 spin_lock(&jz_clock_lock
);
140 val
= readl(jz_clock_base
+ reg
);
142 writel(val
, jz_clock_base
+ reg
);
143 spin_unlock(&jz_clock_lock
);
146 static void jz_clk_reg_clear_bits(int reg
, uint32_t mask
)
150 spin_lock(&jz_clock_lock
);
151 val
= readl(jz_clock_base
+ reg
);
153 writel(val
, jz_clock_base
+ reg
);
154 spin_unlock(&jz_clock_lock
);
157 static int jz_clk_enable_gating(struct clk
*clk
)
159 if (clk
->gate_bit
== JZ4740_CLK_NOT_GATED
)
162 jz_clk_reg_clear_bits(JZ_REG_CLOCK_GATE
, clk
->gate_bit
);
166 static int jz_clk_disable_gating(struct clk
*clk
)
168 if (clk
->gate_bit
== JZ4740_CLK_NOT_GATED
)
171 jz_clk_reg_set_bits(JZ_REG_CLOCK_GATE
, clk
->gate_bit
);
175 static int jz_clk_is_enabled_gating(struct clk
*clk
)
177 if (clk
->gate_bit
== JZ4740_CLK_NOT_GATED
)
180 return !(jz_clk_reg_read(JZ_REG_CLOCK_GATE
) & clk
->gate_bit
);
183 static unsigned long jz_clk_static_get_rate(struct clk
*clk
)
185 return ((struct static_clk
*)clk
)->rate
;
188 static int jz_clk_ko_enable(struct clk
*clk
)
190 jz_clk_reg_set_bits(JZ_REG_CLOCK_CTRL
, JZ_CLOCK_CTRL_KO_ENABLE
);
194 static int jz_clk_ko_disable(struct clk
*clk
)
196 jz_clk_reg_clear_bits(JZ_REG_CLOCK_CTRL
, JZ_CLOCK_CTRL_KO_ENABLE
);
200 static int jz_clk_ko_is_enabled(struct clk
*clk
)
202 return !!(jz_clk_reg_read(JZ_REG_CLOCK_CTRL
) & JZ_CLOCK_CTRL_KO_ENABLE
);
205 static const int pllno
[] = {1, 2, 2, 4};
207 static unsigned long jz_clk_pll_get_rate(struct clk
*clk
)
214 val
= jz_clk_reg_read(JZ_REG_CLOCK_PLL
);
216 if (val
& JZ_CLOCK_PLL_BYPASS
)
217 return clk_get_rate(clk
->parent
);
219 m
= ((val
>> 23) & 0x1ff) + 2;
220 n
= ((val
>> 18) & 0x1f) + 2;
221 od
= (val
>> 16) & 0x3;
223 return clk_get_rate(clk
->parent
) * (m
/ n
) / pllno
[od
];
226 static unsigned long jz_clk_pll_half_get_rate(struct clk
*clk
)
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;
236 static const int jz_clk_main_divs
[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32};
238 static unsigned long jz_clk_main_round_rate(struct clk
*clk
, unsigned long rate
)
240 unsigned long parent_rate
= jz_clk_pll_get_rate(clk
->parent
);
243 div
= parent_rate
/ rate
;
245 return parent_rate
/ 32;
249 div
&= (0x3 << (ffs(div
) - 1));
251 return parent_rate
/ div
;
254 static unsigned long jz_clk_main_get_rate(struct clk
*clk
) {
255 struct main_clk
*mclk
= (struct main_clk
*)clk
;
258 div
= jz_clk_reg_read(JZ_REG_CLOCK_CTRL
);
260 div
>>= mclk
->div_offset
;
263 if (div
>= ARRAY_SIZE(jz_clk_main_divs
))
264 div
= ARRAY_SIZE(jz_clk_main_divs
) - 1;
266 return jz_clk_pll_get_rate(clk
->parent
) / jz_clk_main_divs
[div
];
269 static int jz_clk_main_set_rate(struct clk
*clk
, unsigned long rate
)
271 struct main_clk
*mclk
= (struct main_clk
*)clk
;
274 unsigned long parent_rate
= jz_clk_pll_get_rate(clk
->parent
);
276 rate
= jz_clk_main_round_rate(clk
, rate
);
278 div
= parent_rate
/ rate
;
280 i
= (ffs(div
) - 1) << 1;
281 if (i
> 0 && !(div
& BIT(i
-1)))
284 jz_clk_reg_write_mask(JZ_REG_CLOCK_CTRL
, i
<< mclk
->div_offset
,
285 0xf << mclk
->div_offset
);
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
,
297 static struct static_clk jz_clk_ext
= {
300 .gate_bit
= JZ4740_CLK_NOT_GATED
,
301 .ops
= &jz_clk_static_ops
,
305 static struct clk_ops jz_clk_pll_ops
= {
306 .get_rate
= jz_clk_static_get_rate
,
309 static struct clk jz_clk_pll
= {
311 .parent
= &jz_clk_ext
.clk
,
312 .ops
= &jz_clk_pll_ops
,
315 static struct clk_ops jz_clk_pll_half_ops
= {
316 .get_rate
= jz_clk_pll_half_get_rate
,
319 static struct clk jz_clk_pll_half
= {
321 .parent
= &jz_clk_pll
,
322 .ops
= &jz_clk_pll_half_ops
,
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
,
331 static struct main_clk jz_clk_cpu
= {
334 .parent
= &jz_clk_pll
,
335 .ops
= &jz_clk_main_ops
,
337 .div_offset
= JZ_CLOCK_CTRL_CDIV_OFFSET
,
340 static struct main_clk jz_clk_memory
= {
343 .parent
= &jz_clk_pll
,
344 .ops
= &jz_clk_main_ops
,
346 .div_offset
= JZ_CLOCK_CTRL_MDIV_OFFSET
,
349 static struct main_clk jz_clk_high_speed_peripheral
= {
352 .parent
= &jz_clk_pll
,
353 .ops
= &jz_clk_main_ops
,
355 .div_offset
= JZ_CLOCK_CTRL_HDIV_OFFSET
,
359 static struct main_clk jz_clk_low_speed_peripheral
= {
362 .parent
= &jz_clk_pll
,
363 .ops
= &jz_clk_main_ops
,
365 .div_offset
= JZ_CLOCK_CTRL_PDIV_OFFSET
,
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
,
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_enable(struct clk
*clk
)
410 jz_clk_reg_set_bits(JZ_REG_CLOCK_SLEEP_CTRL
,
411 JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC
);
416 static int jz_clk_udc_disable(struct clk
*clk
)
418 jz_clk_reg_clear_bits(JZ_REG_CLOCK_SLEEP_CTRL
,
419 JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC
);
424 static int jz_clk_udc_is_enabled(struct clk
*clk
)
426 return !!(jz_clk_reg_read(JZ_REG_CLOCK_SLEEP_CTRL
) &
427 JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC
);
429 static int jz_clk_udc_set_parent(struct clk
*clk
, struct clk
*parent
)
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
);
438 clk
->parent
= parent
;
443 static int jz_clk_udc_set_rate(struct clk
*clk
, unsigned long rate
)
447 if (clk
->parent
== &jz_clk_ext
.clk
)
450 div
= clk_get_rate(clk
->parent
) / rate
- 1;
457 jz_clk_reg_write_mask(JZ_REG_CLOCK_CTRL
, div
<< JZ_CLOCK_CTRL_UDIV_OFFSET
,
458 JZ_CLOCK_CTRL_UDIV_MASK
);
462 static unsigned long jz_clk_udc_get_rate(struct clk
*clk
)
466 if (clk
->parent
== &jz_clk_ext
.clk
)
467 return clk_get_rate(clk
->parent
);
469 div
= (jz_clk_reg_read(JZ_REG_CLOCK_CTRL
) & JZ_CLOCK_CTRL_UDIV_MASK
);
470 div
>>= JZ_CLOCK_CTRL_UDIV_OFFSET
;
473 return clk_get_rate(clk
->parent
) / div
;
476 static unsigned long jz_clk_divided_get_rate(struct clk
*clk
)
478 struct divided_clk
*dclk
= (struct divided_clk
*)clk
;
481 if (clk
->parent
== &jz_clk_ext
.clk
)
482 return clk_get_rate(clk
->parent
);
484 div
= (jz_clk_reg_read(dclk
->reg
) & dclk
->mask
) + 1;
486 return clk_get_rate(clk
->parent
) / div
;
489 static int jz_clk_divided_set_rate(struct clk
*clk
, unsigned long rate
)
491 struct divided_clk
*dclk
= (struct divided_clk
*)clk
;
494 if (clk
->parent
== &jz_clk_ext
.clk
)
497 div
= clk_get_rate(clk
->parent
) / rate
- 1;
501 else if(div
> dclk
->mask
)
504 jz_clk_reg_write_mask(dclk
->reg
, div
, dclk
->mask
);
509 static unsigned long jz_clk_ldclk_round_rate(struct clk
*clk
, unsigned long rate
)
512 unsigned long parent_rate
= jz_clk_pll_half_get_rate(clk
->parent
);
514 if (rate
> 150000000)
517 div
= parent_rate
/ rate
;
523 return parent_rate
/ div
;
526 static int jz_clk_ldclk_set_rate(struct clk
*clk
, unsigned long rate
)
530 if (rate
> 150000000)
533 div
= jz_clk_pll_half_get_rate(clk
->parent
) / rate
- 1;
539 jz_clk_reg_write_mask(JZ_REG_CLOCK_CTRL
, div
<< JZ_CLOCK_CTRL_LDIV_OFFSET
,
540 JZ_CLOCK_CTRL_LDIV_MASK
);
545 static unsigned long jz_clk_ldclk_get_rate(struct clk
*clk
)
549 div
= jz_clk_reg_read(JZ_REG_CLOCK_CTRL
) & JZ_CLOCK_CTRL_LDIV_MASK
;
550 div
>>= JZ_CLOCK_CTRL_LDIV_OFFSET
;
552 return jz_clk_pll_half_get_rate(clk
->parent
) / (div
+ 1);
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
,
564 static struct clk jz_clk_ld
= {
566 .gate_bit
= JZ_CLOCK_GATE_LCD
,
567 .parent
= &jz_clk_pll_half
,
568 .ops
= &jz_clk_ops_ld
,
572 static struct clk jz_clk_cim_mclk
= {
574 .parent
= &jz_clk_high_speed_peripheral
.clk
,
577 static struct static_clk jz_clk_cim_pclk
= {
580 .gate_bit
= JZ_CLOCK_GATE_CIM
,
581 .ops
= &jz_clk_static_ops
,
585 static const struct clk_ops jz_clk_i2s_ops
=
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
,
595 static const struct clk_ops jz_clk_spi_ops
=
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
,
605 static const struct clk_ops jz_clk_divided_ops
=
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
,
614 static struct divided_clk jz4740_clock_divided_clks
[] = {
618 .parent
= &jz_clk_pll_half
,
619 .gate_bit
= JZ4740_CLK_NOT_GATED
,
620 .ops
= &jz_clk_divided_ops
,
622 .reg
= JZ_REG_CLOCK_LCD
,
623 .mask
= JZ_CLOCK_LCD_DIV_MASK
,
628 .parent
= &jz_clk_ext
.clk
,
629 .gate_bit
= JZ_CLOCK_GATE_I2S
,
630 .ops
= &jz_clk_i2s_ops
,
632 .reg
= JZ_REG_CLOCK_I2S
,
633 .mask
= JZ_CLOCK_I2S_DIV_MASK
,
638 .parent
= &jz_clk_ext
.clk
,
639 .gate_bit
= JZ_CLOCK_GATE_SPI
,
640 .ops
= &jz_clk_spi_ops
,
642 .reg
= JZ_REG_CLOCK_SPI
,
643 .mask
= JZ_CLOCK_SPI_DIV_MASK
,
648 .parent
= &jz_clk_pll_half
,
649 .gate_bit
= JZ_CLOCK_GATE_MMC
,
650 .ops
= &jz_clk_divided_ops
,
652 .reg
= JZ_REG_CLOCK_MMC
,
653 .mask
= JZ_CLOCK_MMC_DIV_MASK
,
658 .parent
= &jz_clk_pll_half
,
659 .gate_bit
= JZ_CLOCK_GATE_UHC
,
660 .ops
= &jz_clk_divided_ops
,
662 .reg
= JZ_REG_CLOCK_UHC
,
663 .mask
= JZ_CLOCK_UHC_DIV_MASK
,
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
,
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
,
682 static struct clk jz4740_clock_simple_clks
[] = {
685 .parent
= &jz_clk_ext
.clk
,
686 .ops
= &jz_clk_udc_ops
,
690 .parent
= &jz_clk_ext
.clk
,
691 .gate_bit
= JZ_CLOCK_GATE_UART0
,
692 .ops
= &jz_clk_simple_ops
,
696 .parent
= &jz_clk_ext
.clk
,
697 .gate_bit
= JZ_CLOCK_GATE_UART1
,
698 .ops
= &jz_clk_simple_ops
,
702 .parent
= &jz_clk_high_speed_peripheral
.clk
,
703 .gate_bit
= JZ_CLOCK_GATE_UART0
,
704 .ops
= &jz_clk_simple_ops
,
708 .parent
= &jz_clk_high_speed_peripheral
.clk
,
709 .gate_bit
= JZ_CLOCK_GATE_IPU
,
710 .ops
= &jz_clk_simple_ops
,
714 .parent
= &jz_clk_ext
.clk
,
715 .gate_bit
= JZ_CLOCK_GATE_ADC
,
716 .ops
= &jz_clk_simple_ops
,
720 .parent
= &jz_clk_ext
.clk
,
721 .gate_bit
= JZ_CLOCK_GATE_I2C
,
722 .ops
= &jz_clk_simple_ops
,
726 .parent
= &jz_clk_ext
.clk
,
727 .gate_bit
= JZ_CLOCK_GATE_AIC
,
728 .ops
= &jz_clk_simple_ops
,
732 static struct static_clk jz_clk_rtc
= {
735 .gate_bit
= JZ_CLOCK_GATE_RTC
,
736 .ops
= &jz_clk_static_ops
,
741 int clk_enable(struct clk
*clk
)
743 if (!clk
->ops
->enable
)
746 return clk
->ops
->enable(clk
);
748 EXPORT_SYMBOL_GPL(clk_enable
);
750 void clk_disable(struct clk
*clk
)
752 if (clk
->ops
->disable
)
753 clk
->ops
->disable(clk
);
755 EXPORT_SYMBOL_GPL(clk_disable
);
757 int clk_is_enabled(struct clk
*clk
)
759 if (clk
->ops
->is_enabled
)
760 return clk
->ops
->is_enabled(clk
);
765 unsigned long clk_get_rate(struct clk
*clk
)
767 if (clk
->ops
->get_rate
)
768 return clk
->ops
->get_rate(clk
);
770 return clk_get_rate(clk
->parent
);
774 EXPORT_SYMBOL_GPL(clk_get_rate
);
776 int clk_set_rate(struct clk
*clk
, unsigned long rate
)
778 if (!clk
->ops
->set_rate
)
780 return clk
->ops
->set_rate(clk
, rate
);
782 EXPORT_SYMBOL_GPL(clk_set_rate
);
784 long clk_round_rate(struct clk
*clk
, unsigned long rate
)
786 if (clk
->ops
->round_rate
)
787 return clk
->ops
->round_rate(clk
, rate
);
791 EXPORT_SYMBOL_GPL(clk_round_rate
);
793 int clk_set_parent(struct clk
*clk
, struct clk
*parent
)
797 if (!clk
->ops
->set_parent
)
801 ret
= clk
->ops
->set_parent(clk
, parent
);
804 jz4740_clock_debugfs_update_parent(clk
);
808 EXPORT_SYMBOL_GPL(clk_set_parent
);
810 struct clk
*clk_get(struct device
*dev
, const char *name
)
814 list_for_each_entry(clk
, &jz_clocks
, list
) {
815 if (strcmp(clk
->name
, name
) == 0)
818 return ERR_PTR(-ENOENT
);
820 EXPORT_SYMBOL_GPL(clk_get
);
822 void clk_put(struct clk
*clk
)
825 EXPORT_SYMBOL_GPL(clk_put
);
828 inline static void clk_add(struct clk
*clk
)
830 list_add_tail(&clk
->list
, &jz_clocks
);
832 jz4740_clock_debugfs_add_clk(clk
);
835 static void clk_register_clks(void)
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
);
847 clk_add(&jz_clk_cim_mclk
);
848 clk_add(&jz_clk_cim_pclk
.clk
);
849 clk_add(&jz_clk_rtc
.clk
);
851 for (i
= 0; i
< ARRAY_SIZE(jz4740_clock_divided_clks
); ++i
)
852 clk_add(&jz4740_clock_divided_clks
[i
].clk
);
854 for (i
= 0; i
< ARRAY_SIZE(jz4740_clock_simple_clks
); ++i
)
855 clk_add(&jz4740_clock_simple_clks
[i
]);
858 void jz4740_clock_set_wait_mode(enum jz4740_wait_mode mode
)
861 case JZ4740_WAIT_MODE_IDLE
:
862 jz_clk_reg_clear_bits(JZ_REG_CLOCK_LOW_POWER
, JZ_CLOCK_LOW_POWER_MODE_SLEEP
);
864 case JZ4740_WAIT_MODE_SLEEP
:
865 jz_clk_reg_set_bits(JZ_REG_CLOCK_LOW_POWER
, JZ_CLOCK_LOW_POWER_MODE_SLEEP
);
870 void jz4740_clock_udc_disable_auto_suspend(void)
872 jz_clk_reg_clear_bits(JZ_REG_CLOCK_GATE
, JZ_CLOCK_GATE_UDC
);
874 EXPORT_SYMBOL_GPL(jz4740_clock_udc_disable_auto_suspend
);
876 void jz4740_clock_udc_enable_auto_suspend(void)
878 jz_clk_reg_set_bits(JZ_REG_CLOCK_GATE
, JZ_CLOCK_GATE_UDC
);
880 EXPORT_SYMBOL_GPL(jz4740_clock_udc_enable_auto_suspend
);
882 void jz4740_clock_suspend(void)
884 jz_clk_reg_set_bits(JZ_REG_CLOCK_GATE
,
885 JZ_CLOCK_GATE_TCU
| JZ_CLOCK_GATE_DMAC
| JZ_CLOCK_GATE_UART0
);
887 jz_clk_reg_clear_bits(JZ_REG_CLOCK_PLL
, JZ_CLOCK_PLL_ENABLED
);
890 void jz4740_clock_resume(void)
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);
895 jz_clk_reg_clear_bits(JZ_REG_CLOCK_GATE
,
896 JZ_CLOCK_GATE_TCU
| JZ_CLOCK_GATE_DMAC
| JZ_CLOCK_GATE_UART0
);
899 int jz4740_clock_init(void)
903 jz_clock_base
= ioremap(CPHYSADDR(CPM_BASE
), 0x100);
907 spin_lock_init(&jz_clock_lock
);
909 jz_clk_ext
.rate
= jz4740_clock_bdata
.ext_rate
;
910 jz_clk_rtc
.rate
= jz4740_clock_bdata
.rtc_rate
;
912 val
= jz_clk_reg_read(JZ_REG_CLOCK_SPI
);
914 if (val
& JZ_CLOCK_SPI_SRC_PLL
)
915 jz4740_clock_divided_clks
[1].clk
.parent
= &jz_clk_pll_half
;
917 val
= jz_clk_reg_read(JZ_REG_CLOCK_CTRL
);
919 if (val
& JZ_CLOCK_CTRL_I2S_SRC_PLL
)
920 jz4740_clock_divided_clks
[0].clk
.parent
= &jz_clk_pll_half
;
922 if (val
& JZ_CLOCK_CTRL_UDC_SRC_PLL
)
923 jz4740_clock_simple_clks
[0].parent
= &jz_clk_pll_half
;
925 jz4740_clock_debugfs_init();