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>
26 #include <asm/mach-jz4740/base.h>
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
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
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)
72 #define JZ_CLOCK_I2S_DIV_MASK 0x01ff
74 #define JZ_CLOCK_LCD_DIV_MASK 0x01ff
76 #define JZ_CLOCK_MMC_DIV_MASK 0x001f
78 #define JZ_CLOCK_UHC_DIV_MASK 0x000f
80 #define JZ_CLOCK_SPI_SRC_PLL BIT(31)
81 #define JZ_CLOCK_SPI_DIV_MASK 0x000f
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
94 #define JZ_CLOCK_LOW_POWER_MODE_DOZE BIT(2)
95 #define JZ_CLOCK_LOW_POWER_MODE_SLEEP BIT(0)
97 #define JZ_CLOCK_SLEEP_CTRL_SUSPEND_UHC BIT(7)
98 #define JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC BIT(6)
100 static void __iomem
*jz_clock_base
;
101 static spinlock_t jz_clock_lock
;
102 static LIST_HEAD(jz_clocks
);
120 static uint32_t jz_clk_reg_read(int reg
)
122 return readl(jz_clock_base
+ reg
);
125 static void jz_clk_reg_write_mask(int reg
, uint32_t val
, uint32_t mask
)
129 spin_lock(&jz_clock_lock
);
130 val2
= readl(jz_clock_base
+ reg
);
133 writel(val2
, jz_clock_base
+ reg
);
134 spin_unlock(&jz_clock_lock
);
137 static void jz_clk_reg_set_bits(int reg
, uint32_t mask
)
141 spin_lock(&jz_clock_lock
);
142 val
= readl(jz_clock_base
+ reg
);
144 writel(val
, jz_clock_base
+ reg
);
145 spin_unlock(&jz_clock_lock
);
148 static void jz_clk_reg_clear_bits(int reg
, uint32_t mask
)
152 spin_lock(&jz_clock_lock
);
153 val
= readl(jz_clock_base
+ reg
);
155 writel(val
, jz_clock_base
+ reg
);
156 spin_unlock(&jz_clock_lock
);
159 static int jz_clk_enable_gating(struct clk
*clk
)
161 if (clk
->gate_bit
== JZ4740_CLK_NOT_GATED
)
164 jz_clk_reg_clear_bits(JZ_REG_CLOCK_GATE
, clk
->gate_bit
);
168 static int jz_clk_disable_gating(struct clk
*clk
)
170 if (clk
->gate_bit
== JZ4740_CLK_NOT_GATED
)
173 jz_clk_reg_set_bits(JZ_REG_CLOCK_GATE
, clk
->gate_bit
);
177 static int jz_clk_is_enabled_gating(struct clk
*clk
)
179 if (clk
->gate_bit
== JZ4740_CLK_NOT_GATED
)
182 return !(jz_clk_reg_read(JZ_REG_CLOCK_GATE
) & clk
->gate_bit
);
185 static unsigned long jz_clk_static_get_rate(struct clk
*clk
)
187 return ((struct static_clk
*)clk
)->rate
;
190 static int jz_clk_ko_enable(struct clk
*clk
)
192 jz_clk_reg_set_bits(JZ_REG_CLOCK_CTRL
, JZ_CLOCK_CTRL_KO_ENABLE
);
196 static int jz_clk_ko_disable(struct clk
*clk
)
198 jz_clk_reg_clear_bits(JZ_REG_CLOCK_CTRL
, JZ_CLOCK_CTRL_KO_ENABLE
);
202 static int jz_clk_ko_is_enabled(struct clk
*clk
)
204 return !!(jz_clk_reg_read(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
) / n
) * m
) / 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
)
258 struct main_clk
*mclk
= (struct main_clk
*)clk
;
261 div
= jz_clk_reg_read(JZ_REG_CLOCK_CTRL
);
263 div
>>= mclk
->div_offset
;
266 if (div
>= ARRAY_SIZE(jz_clk_main_divs
))
267 div
= ARRAY_SIZE(jz_clk_main_divs
) - 1;
269 return jz_clk_pll_get_rate(clk
->parent
) / jz_clk_main_divs
[div
];
272 static int jz_clk_main_set_rate(struct clk
*clk
, unsigned long rate
)
274 struct main_clk
*mclk
= (struct main_clk
*)clk
;
277 unsigned long parent_rate
= jz_clk_pll_get_rate(clk
->parent
);
279 rate
= jz_clk_main_round_rate(clk
, rate
);
281 div
= parent_rate
/ rate
;
283 i
= (ffs(div
) - 1) << 1;
284 if (i
> 0 && !(div
& BIT(i
-1)))
287 jz_clk_reg_write_mask(JZ_REG_CLOCK_CTRL
, i
<< mclk
->div_offset
,
288 0xf << mclk
->div_offset
);
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
,
300 static struct static_clk jz_clk_ext
= {
303 .gate_bit
= JZ4740_CLK_NOT_GATED
,
304 .ops
= &jz_clk_static_ops
,
308 static struct clk_ops jz_clk_pll_ops
= {
309 .get_rate
= jz_clk_pll_get_rate
,
312 static struct clk jz_clk_pll
= {
314 .parent
= &jz_clk_ext
.clk
,
315 .ops
= &jz_clk_pll_ops
,
318 static struct clk_ops jz_clk_pll_half_ops
= {
319 .get_rate
= jz_clk_pll_half_get_rate
,
322 static struct clk jz_clk_pll_half
= {
324 .parent
= &jz_clk_pll
,
325 .ops
= &jz_clk_pll_half_ops
,
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
,
334 static struct main_clk jz_clk_cpu
= {
337 .parent
= &jz_clk_pll
,
338 .ops
= &jz_clk_main_ops
,
340 .div_offset
= JZ_CLOCK_CTRL_CDIV_OFFSET
,
343 static struct main_clk jz_clk_memory
= {
346 .parent
= &jz_clk_pll
,
347 .ops
= &jz_clk_main_ops
,
349 .div_offset
= JZ_CLOCK_CTRL_MDIV_OFFSET
,
352 static struct main_clk jz_clk_high_speed_peripheral
= {
355 .parent
= &jz_clk_pll
,
356 .ops
= &jz_clk_main_ops
,
358 .div_offset
= JZ_CLOCK_CTRL_HDIV_OFFSET
,
362 static struct main_clk jz_clk_low_speed_peripheral
= {
365 .parent
= &jz_clk_pll
,
366 .ops
= &jz_clk_main_ops
,
368 .div_offset
= JZ_CLOCK_CTRL_PDIV_OFFSET
,
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
,
377 static struct clk jz_clk_ko
= {
379 .parent
= &jz_clk_memory
.clk
,
380 .ops
= &jz_clk_ko_ops
,
383 static int jz_clk_spi_set_parent(struct clk
*clk
, struct clk
*parent
)
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
);
392 clk
->parent
= parent
;
397 static int jz_clk_i2s_set_parent(struct clk
*clk
, struct clk
*parent
)
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
);
406 clk
->parent
= parent
;
411 static int jz_clk_udc_enable(struct clk
*clk
)
413 jz_clk_reg_set_bits(JZ_REG_CLOCK_SLEEP_CTRL
,
414 JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC
);
419 static int jz_clk_udc_disable(struct clk
*clk
)
421 jz_clk_reg_clear_bits(JZ_REG_CLOCK_SLEEP_CTRL
,
422 JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC
);
427 static int jz_clk_udc_is_enabled(struct clk
*clk
)
429 return !!(jz_clk_reg_read(JZ_REG_CLOCK_SLEEP_CTRL
) &
430 JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC
);
433 static int jz_clk_udc_set_parent(struct clk
*clk
, struct clk
*parent
)
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
);
442 clk
->parent
= parent
;
447 static int jz_clk_udc_set_rate(struct clk
*clk
, unsigned long rate
)
451 if (clk
->parent
== &jz_clk_ext
.clk
)
454 div
= clk_get_rate(clk
->parent
) / rate
- 1;
461 jz_clk_reg_write_mask(JZ_REG_CLOCK_CTRL
, div
<< JZ_CLOCK_CTRL_UDIV_OFFSET
,
462 JZ_CLOCK_CTRL_UDIV_MASK
);
466 static unsigned long jz_clk_udc_get_rate(struct clk
*clk
)
470 if (clk
->parent
== &jz_clk_ext
.clk
)
471 return clk_get_rate(clk
->parent
);
473 div
= (jz_clk_reg_read(JZ_REG_CLOCK_CTRL
) & JZ_CLOCK_CTRL_UDIV_MASK
);
474 div
>>= JZ_CLOCK_CTRL_UDIV_OFFSET
;
477 return clk_get_rate(clk
->parent
) / div
;
480 static unsigned long jz_clk_divided_get_rate(struct clk
*clk
)
482 struct divided_clk
*dclk
= (struct divided_clk
*)clk
;
485 if (clk
->parent
== &jz_clk_ext
.clk
)
486 return clk_get_rate(clk
->parent
);
488 div
= (jz_clk_reg_read(dclk
->reg
) & dclk
->mask
) + 1;
490 return clk_get_rate(clk
->parent
) / div
;
493 static int jz_clk_divided_set_rate(struct clk
*clk
, unsigned long rate
)
495 struct divided_clk
*dclk
= (struct divided_clk
*)clk
;
498 if (clk
->parent
== &jz_clk_ext
.clk
)
501 div
= clk_get_rate(clk
->parent
) / rate
- 1;
505 else if (div
> dclk
->mask
)
508 jz_clk_reg_write_mask(dclk
->reg
, div
, dclk
->mask
);
513 static unsigned long jz_clk_ldclk_round_rate(struct clk
*clk
, unsigned long rate
)
516 unsigned long parent_rate
= jz_clk_pll_half_get_rate(clk
->parent
);
518 if (rate
> 150000000)
521 div
= parent_rate
/ rate
;
527 return parent_rate
/ div
;
530 static int jz_clk_ldclk_set_rate(struct clk
*clk
, unsigned long rate
)
534 if (rate
> 150000000)
537 div
= jz_clk_pll_half_get_rate(clk
->parent
) / rate
- 1;
543 jz_clk_reg_write_mask(JZ_REG_CLOCK_CTRL
, div
<< JZ_CLOCK_CTRL_LDIV_OFFSET
,
544 JZ_CLOCK_CTRL_LDIV_MASK
);
549 static unsigned long jz_clk_ldclk_get_rate(struct clk
*clk
)
553 div
= jz_clk_reg_read(JZ_REG_CLOCK_CTRL
) & JZ_CLOCK_CTRL_LDIV_MASK
;
554 div
>>= JZ_CLOCK_CTRL_LDIV_OFFSET
;
556 return jz_clk_pll_half_get_rate(clk
->parent
) / (div
+ 1);
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
,
568 static struct clk jz_clk_ld
= {
570 .gate_bit
= JZ_CLOCK_GATE_LCD
,
571 .parent
= &jz_clk_pll_half
,
572 .ops
= &jz_clk_ops_ld
,
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
,
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
,
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
,
601 static struct divided_clk jz4740_clock_divided_clks
[] = {
605 .parent
= &jz_clk_ext
.clk
,
606 .gate_bit
= JZ_CLOCK_GATE_I2S
,
607 .ops
= &jz_clk_i2s_ops
,
609 .reg
= JZ_REG_CLOCK_I2S
,
610 .mask
= JZ_CLOCK_I2S_DIV_MASK
,
615 .parent
= &jz_clk_ext
.clk
,
616 .gate_bit
= JZ_CLOCK_GATE_SPI
,
617 .ops
= &jz_clk_spi_ops
,
619 .reg
= JZ_REG_CLOCK_SPI
,
620 .mask
= JZ_CLOCK_SPI_DIV_MASK
,
625 .parent
= &jz_clk_pll_half
,
626 .gate_bit
= JZ4740_CLK_NOT_GATED
,
627 .ops
= &jz_clk_divided_ops
,
629 .reg
= JZ_REG_CLOCK_LCD
,
630 .mask
= JZ_CLOCK_LCD_DIV_MASK
,
635 .parent
= &jz_clk_pll_half
,
636 .gate_bit
= JZ_CLOCK_GATE_MMC
,
637 .ops
= &jz_clk_divided_ops
,
639 .reg
= JZ_REG_CLOCK_MMC
,
640 .mask
= JZ_CLOCK_MMC_DIV_MASK
,
645 .parent
= &jz_clk_pll_half
,
646 .gate_bit
= JZ_CLOCK_GATE_UHC
,
647 .ops
= &jz_clk_divided_ops
,
649 .reg
= JZ_REG_CLOCK_UHC
,
650 .mask
= JZ_CLOCK_UHC_DIV_MASK
,
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
,
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
,
669 static struct clk jz4740_clock_simple_clks
[] = {
672 .parent
= &jz_clk_ext
.clk
,
673 .ops
= &jz_clk_udc_ops
,
677 .parent
= &jz_clk_ext
.clk
,
678 .gate_bit
= JZ_CLOCK_GATE_UART0
,
679 .ops
= &jz_clk_simple_ops
,
683 .parent
= &jz_clk_ext
.clk
,
684 .gate_bit
= JZ_CLOCK_GATE_UART1
,
685 .ops
= &jz_clk_simple_ops
,
689 .parent
= &jz_clk_high_speed_peripheral
.clk
,
690 .gate_bit
= JZ_CLOCK_GATE_DMAC
,
691 .ops
= &jz_clk_simple_ops
,
695 .parent
= &jz_clk_high_speed_peripheral
.clk
,
696 .gate_bit
= JZ_CLOCK_GATE_IPU
,
697 .ops
= &jz_clk_simple_ops
,
701 .parent
= &jz_clk_ext
.clk
,
702 .gate_bit
= JZ_CLOCK_GATE_ADC
,
703 .ops
= &jz_clk_simple_ops
,
707 .parent
= &jz_clk_ext
.clk
,
708 .gate_bit
= JZ_CLOCK_GATE_I2C
,
709 .ops
= &jz_clk_simple_ops
,
713 .parent
= &jz_clk_ext
.clk
,
714 .gate_bit
= JZ_CLOCK_GATE_AIC
,
715 .ops
= &jz_clk_simple_ops
,
719 static struct static_clk jz_clk_rtc
= {
722 .gate_bit
= JZ_CLOCK_GATE_RTC
,
723 .ops
= &jz_clk_static_ops
,
728 int clk_enable(struct clk
*clk
)
730 if (!clk
->ops
->enable
)
733 return clk
->ops
->enable(clk
);
735 EXPORT_SYMBOL_GPL(clk_enable
);
737 void clk_disable(struct clk
*clk
)
739 if (clk
->ops
->disable
)
740 clk
->ops
->disable(clk
);
742 EXPORT_SYMBOL_GPL(clk_disable
);
744 int clk_is_enabled(struct clk
*clk
)
746 if (clk
->ops
->is_enabled
)
747 return clk
->ops
->is_enabled(clk
);
752 unsigned long clk_get_rate(struct clk
*clk
)
754 if (clk
->ops
->get_rate
)
755 return clk
->ops
->get_rate(clk
);
757 return clk_get_rate(clk
->parent
);
761 EXPORT_SYMBOL_GPL(clk_get_rate
);
763 int clk_set_rate(struct clk
*clk
, unsigned long rate
)
765 if (!clk
->ops
->set_rate
)
767 return clk
->ops
->set_rate(clk
, rate
);
769 EXPORT_SYMBOL_GPL(clk_set_rate
);
771 long clk_round_rate(struct clk
*clk
, unsigned long rate
)
773 if (clk
->ops
->round_rate
)
774 return clk
->ops
->round_rate(clk
, rate
);
778 EXPORT_SYMBOL_GPL(clk_round_rate
);
780 int clk_set_parent(struct clk
*clk
, struct clk
*parent
)
785 if (!clk
->ops
->set_parent
)
788 enabled
= clk_is_enabled(clk
);
791 ret
= clk
->ops
->set_parent(clk
, parent
);
795 jz4740_clock_debugfs_update_parent(clk
);
799 EXPORT_SYMBOL_GPL(clk_set_parent
);
801 struct clk
*clk_get(struct device
*dev
, const char *name
)
805 list_for_each_entry(clk
, &jz_clocks
, list
) {
806 if (strcmp(clk
->name
, name
) == 0)
809 return ERR_PTR(-ENXIO
);
811 EXPORT_SYMBOL_GPL(clk_get
);
813 void clk_put(struct clk
*clk
)
816 EXPORT_SYMBOL_GPL(clk_put
);
818 static inline void clk_add(struct clk
*clk
)
820 list_add_tail(&clk
->list
, &jz_clocks
);
822 jz4740_clock_debugfs_add_clk(clk
);
825 static void clk_register_clks(void)
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
);
837 clk_add(&jz_clk_rtc
.clk
);
839 for (i
= 0; i
< ARRAY_SIZE(jz4740_clock_divided_clks
); ++i
)
840 clk_add(&jz4740_clock_divided_clks
[i
].clk
);
842 for (i
= 0; i
< ARRAY_SIZE(jz4740_clock_simple_clks
); ++i
)
843 clk_add(&jz4740_clock_simple_clks
[i
]);
846 void jz4740_clock_set_wait_mode(enum jz4740_wait_mode mode
)
849 case JZ4740_WAIT_MODE_IDLE
:
850 jz_clk_reg_clear_bits(JZ_REG_CLOCK_LOW_POWER
, JZ_CLOCK_LOW_POWER_MODE_SLEEP
);
852 case JZ4740_WAIT_MODE_SLEEP
:
853 jz_clk_reg_set_bits(JZ_REG_CLOCK_LOW_POWER
, JZ_CLOCK_LOW_POWER_MODE_SLEEP
);
858 void jz4740_clock_udc_disable_auto_suspend(void)
860 jz_clk_reg_clear_bits(JZ_REG_CLOCK_GATE
, JZ_CLOCK_GATE_UDC
);
862 EXPORT_SYMBOL_GPL(jz4740_clock_udc_disable_auto_suspend
);
864 void jz4740_clock_udc_enable_auto_suspend(void)
866 jz_clk_reg_set_bits(JZ_REG_CLOCK_GATE
, JZ_CLOCK_GATE_UDC
);
868 EXPORT_SYMBOL_GPL(jz4740_clock_udc_enable_auto_suspend
);
870 void jz4740_clock_suspend(void)
872 jz_clk_reg_set_bits(JZ_REG_CLOCK_GATE
,
873 JZ_CLOCK_GATE_TCU
| JZ_CLOCK_GATE_DMAC
| JZ_CLOCK_GATE_UART0
);
875 jz_clk_reg_clear_bits(JZ_REG_CLOCK_PLL
, JZ_CLOCK_PLL_ENABLED
);
878 void jz4740_clock_resume(void)
882 jz_clk_reg_set_bits(JZ_REG_CLOCK_PLL
, JZ_CLOCK_PLL_ENABLED
);
885 pll
= jz_clk_reg_read(JZ_REG_CLOCK_PLL
);
886 } while (!(pll
& JZ_CLOCK_PLL_STABLE
));
888 jz_clk_reg_clear_bits(JZ_REG_CLOCK_GATE
,
889 JZ_CLOCK_GATE_TCU
| JZ_CLOCK_GATE_DMAC
| JZ_CLOCK_GATE_UART0
);
892 static int jz4740_clock_init(void)
896 jz_clock_base
= ioremap(JZ4740_CPM_BASE_ADDR
, 0x100);
900 spin_lock_init(&jz_clock_lock
);
902 jz_clk_ext
.rate
= jz4740_clock_bdata
.ext_rate
;
903 jz_clk_rtc
.rate
= jz4740_clock_bdata
.rtc_rate
;
905 val
= jz_clk_reg_read(JZ_REG_CLOCK_SPI
);
907 if (val
& JZ_CLOCK_SPI_SRC_PLL
)
908 jz4740_clock_divided_clks
[1].clk
.parent
= &jz_clk_pll_half
;
910 val
= jz_clk_reg_read(JZ_REG_CLOCK_CTRL
);
912 if (val
& JZ_CLOCK_CTRL_I2S_SRC_PLL
)
913 jz4740_clock_divided_clks
[0].clk
.parent
= &jz_clk_pll_half
;
915 if (val
& JZ_CLOCK_CTRL_UDC_SRC_PLL
)
916 jz4740_clock_simple_clks
[0].parent
= &jz_clk_pll_half
;
918 jz4740_clock_debugfs_init();
924 arch_initcall(jz4740_clock_init
);