2 * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
3 * JZ4740 SoC TCU 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 #define JZ_REG_CLOCK_CTRL 0x00
26 #define JZ_REG_CLOCK_PLL 0x10
27 #define JZ_REG_CLOCK_GATE 0x20
28 #define JZ_REG_CLOCK_I2S 0x60
29 #define JZ_REG_CLOCK_LCD 0x64
30 #define JZ_REG_CLOCK_MMC 0x68
31 #define JZ_REG_CLOCK_UHC 0x6C
32 #define JZ_REG_CLOCK_SPI 0x74
34 #define JZ_CLOCK_CTRL_I2S_SRC_PLL BIT(31)
35 #define JZ_CLOCK_CTRL_KO_ENABLE BIT(30)
36 #define JZ_CLOCK_CTRL_UDC_SRC_PLL BIT(29)
37 #define JZ_CLOCK_CTRL_UDIV_MASK 0x1f800000
38 #define JZ_CLOCK_CTRL_CHANGE_ENABLE BIT(22)
39 #define JZ_CLOCK_CTRL_PLL_HALF BIT(21)
40 #define JZ_CLOCK_CTRL_LDIV_MASK 0x001f0000
41 #define JZ_CLOCK_CTRL_UDIV_OFFSET 23
42 #define JZ_CLOCK_CTRL_LDIV_OFFSET 16
43 #define JZ_CLOCK_CTRL_MDIV_OFFSET 12
44 #define JZ_CLOCK_CTRL_PDIV_OFFSET 8
45 #define JZ_CLOCK_CTRL_HDIV_OFFSET 4
46 #define JZ_CLOCK_CTRL_CDIV_OFFSET 0
48 #define JZ_CLOCK_GATE_UART0 BIT(0)
49 #define JZ_CLOCK_GATE_TCU BIT(1)
50 #define JZ_CLOCK_GATE_RTC BIT(2)
51 #define JZ_CLOCK_GATE_I2C BIT(3)
52 #define JZ_CLOCK_GATE_SPI BIT(4)
53 #define JZ_CLOCK_GATE_AIC_PCLK BIT(5)
54 #define JZ_CLOCK_GATE_AIC BIT(6)
55 #define JZ_CLOCK_GATE_MMC BIT(7)
56 #define JZ_CLOCK_GATE_ADC BIT(8)
57 #define JZ_CLOCK_GATE_CIM BIT(9)
58 #define JZ_CLOCK_GATE_LCD BIT(10)
59 #define JZ_CLOCK_GATE_UDC BIT(11)
60 #define JZ_CLOCK_GATE_DMAC BIT(12)
61 #define JZ_CLOCK_GATE_IPU BIT(13)
62 #define JZ_CLOCK_GATE_UHC BIT(14)
63 #define JZ_CLOCK_GATE_UART1 BIT(15)
65 #define JZ_CLOCK_I2S_DIV_MASK 0x01ff
67 #define JZ_CLOCK_LCD_DIV_MASK 0x01ff
69 #define JZ_CLOCK_MMC_DIV_MASK 0x001f
71 #define JZ_CLOCK_UHC_DIV_MASK 0x000f
73 #define JZ_CLOCK_SPI_SRC_PLL BIT(31)
74 #define JZ_CLOCK_SPI_DIV_MASK 0x000f
76 #define JZ_CLOCK_PLL_M_MASK 0x01ff
77 #define JZ_CLOCK_PLL_N_MASK 0x001f
78 #define JZ_CLOCK_PLL_OD_MASK 0x0003
79 #define JZ_CLOCK_PLL_STABLE BIT(10)
80 #define JZ_CLOCK_PLL_BYPASS BIT(9)
81 #define JZ_CLOCK_PLL_ENABLED BIT(8)
82 #define JZ_CLOCK_PLL_STABLIZE_MASK 0x000f
83 #define JZ_CLOCK_PLL_M_OFFSET 23
84 #define JZ_CLOCK_PLL_N_OFFSET 18
85 #define JZ_CLOCK_PLL_OD_OFFSET 16
87 static void __iomem
*jz_clock_base
;
88 static spinlock_t jz_clock_lock
;
89 static LIST_HEAD(jz_clocks
);
97 unsigned long (*get_rate
)(struct clk
* clk
);
98 unsigned long (*round_rate
)(struct clk
*clk
, unsigned long rate
);
99 int (*set_rate
)(struct clk
* clk
, unsigned long rate
);
100 int (*enable
)(struct clk
* clk
);
101 int (*disable
)(struct clk
* clk
);
103 int (*set_parent
)(struct clk
* clk
, struct clk
*parent
);
104 struct list_head list
;
123 static uint32_t jz_clk_reg_read(int reg
)
125 return readl(jz_clock_base
+ reg
);
128 static void jz_clk_reg_write_mask(int reg
, uint32_t val
, uint32_t mask
)
132 spin_lock(&jz_clock_lock
);
133 val2
= readl(jz_clock_base
+ reg
);
136 writel(val2
, jz_clock_base
+ reg
);
137 spin_unlock(&jz_clock_lock
);
140 static void jz_clk_reg_set_bits(int reg
, uint32_t mask
)
144 spin_lock(&jz_clock_lock
);
145 val
= readl(jz_clock_base
+ reg
);
147 writel(val
, jz_clock_base
+ reg
);
148 spin_unlock(&jz_clock_lock
);
151 static void jz_clk_reg_clear_bits(int reg
, uint32_t mask
)
155 spin_lock(&jz_clock_lock
);
156 val
= readl(jz_clock_base
+ reg
);
158 writel(val
, jz_clock_base
+ reg
);
159 spin_unlock(&jz_clock_lock
);
162 static int jz_clk_enable_gating(struct clk
*clk
)
164 jz_clk_reg_clear_bits(JZ_REG_CLOCK_GATE
, clk
->gate_bit
);
168 static int jz_clk_disable_gating(struct clk
*clk
)
170 jz_clk_reg_set_bits(JZ_REG_CLOCK_GATE
, clk
->gate_bit
);
174 static unsigned long jz_clk_static_get_rate(struct clk
*clk
)
176 return ((struct static_clk
*)clk
)->rate
;
179 static int jz_clk_ko_enable(struct clk
* clk
)
181 jz_clk_reg_set_bits(JZ_REG_CLOCK_CTRL
, JZ_CLOCK_CTRL_KO_ENABLE
);
185 static int jz_clk_ko_disable(struct clk
* clk
)
187 jz_clk_reg_clear_bits(JZ_REG_CLOCK_CTRL
, JZ_CLOCK_CTRL_KO_ENABLE
);
192 static const int pllno
[] = {1, 2, 2, 4};
194 static unsigned long jz_clk_pll_get_rate(struct clk
*clk
)
201 val
= jz_clk_reg_read(JZ_REG_CLOCK_PLL
);
203 if (val
& JZ_CLOCK_PLL_BYPASS
)
204 return clk_get_rate(clk
->parent
);
206 m
= ((val
>> 23) & 0x1ff) + 2;
207 n
= ((val
>> 18) & 0x1f) + 2;
208 od
= (val
>> 16) & 0x3;
210 return clk_get_rate(clk
->parent
) * (m
/ n
) / pllno
[od
];
213 static unsigned long jz_clk_pll_half_get_rate(struct clk
*clk
)
217 reg
= jz_clk_reg_read(JZ_REG_CLOCK_CTRL
);
218 if (reg
& JZ_CLOCK_CTRL_PLL_HALF
)
219 return jz_clk_pll_get_rate(clk
->parent
);
220 return jz_clk_pll_get_rate(clk
->parent
) >> 1;
225 static const int jz_clk_main_divs
[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32};
227 static unsigned long jz_clk_main_round_rate(struct clk
*clk
, unsigned long rate
)
229 unsigned long parent_rate
= jz_clk_pll_get_rate(clk
->parent
);
232 div
= parent_rate
/ rate
;
234 return parent_rate
/ 32;
238 div
&= (0x3 << (ffs(div
) - 1));
240 return parent_rate
/ div
;
243 static unsigned long jz_clk_main_get_rate(struct clk
*clk
) {
244 struct main_clk
*mclk
= (struct main_clk
*)clk
;
247 div
= jz_clk_reg_read(JZ_REG_CLOCK_CTRL
);
249 div
>>= mclk
->div_offset
;
252 if (div
>= ARRAY_SIZE(jz_clk_main_divs
))
253 div
= ARRAY_SIZE(jz_clk_main_divs
) - 1;
255 return jz_clk_pll_get_rate(clk
->parent
) / jz_clk_main_divs
[div
];
258 static int jz_clk_main_set_rate(struct clk
*clk
, unsigned long rate
)
260 struct main_clk
*mclk
= (struct main_clk
*)clk
;
263 unsigned long parent_rate
= jz_clk_pll_get_rate(clk
->parent
);
265 rate
= jz_clk_main_round_rate(clk
, rate
);
267 div
= parent_rate
/ rate
;
269 i
= (ffs(div
) - 1) << 1;
270 if (i
> 0 && !(div
& BIT(i
-1)))
273 jz_clk_reg_write_mask(JZ_REG_CLOCK_CTRL
, i
<< mclk
->div_offset
,
274 0xf << mclk
->div_offset
);
280 static struct static_clk jz_clk_ext
= {
283 .get_rate
= jz_clk_static_get_rate
,
287 static struct clk jz_clk_pll
= {
289 .parent
= &jz_clk_ext
.clk
,
290 .get_rate
= jz_clk_pll_get_rate
,
293 static struct clk jz_clk_pll_half
= {
295 .parent
= &jz_clk_pll
,
296 .get_rate
= jz_clk_pll_half_get_rate
,
299 static struct main_clk jz_clk_cpu
= {
302 .parent
= &jz_clk_pll
,
303 .get_rate
= jz_clk_main_get_rate
,
304 .set_rate
= jz_clk_main_set_rate
,
305 .round_rate
= jz_clk_main_round_rate
,
307 .div_offset
= JZ_CLOCK_CTRL_CDIV_OFFSET
,
310 static struct main_clk jz_clk_memory
= {
313 .parent
= &jz_clk_pll
,
314 .get_rate
= jz_clk_main_get_rate
,
315 .set_rate
= jz_clk_main_set_rate
,
316 .round_rate
= jz_clk_main_round_rate
,
318 .div_offset
= JZ_CLOCK_CTRL_MDIV_OFFSET
,
321 static struct main_clk jz_clk_high_speed_peripheral
= {
324 .parent
= &jz_clk_pll
,
325 .get_rate
= jz_clk_main_get_rate
,
326 .set_rate
= jz_clk_main_set_rate
,
327 .round_rate
= jz_clk_main_round_rate
,
329 .div_offset
= JZ_CLOCK_CTRL_HDIV_OFFSET
,
333 static struct main_clk jz_clk_low_speed_peripheral
= {
336 .parent
= &jz_clk_pll
,
337 .get_rate
= jz_clk_main_get_rate
,
338 .set_rate
= jz_clk_main_set_rate
,
340 .div_offset
= JZ_CLOCK_CTRL_PDIV_OFFSET
,
343 static struct clk jz_clk_ko
= {
345 .parent
= &jz_clk_memory
.clk
,
346 .enable
= jz_clk_ko_enable
,
347 .disable
= jz_clk_ko_disable
,
350 static int jz_clk_spi_set_parent(struct clk
*clk
, struct clk
*parent
)
352 if (parent
== &jz_clk_pll
)
353 jz_clk_reg_set_bits(JZ_CLOCK_SPI_SRC_PLL
, JZ_REG_CLOCK_SPI
);
354 else if(parent
== &jz_clk_ext
.clk
)
355 jz_clk_reg_clear_bits(JZ_CLOCK_SPI_SRC_PLL
, JZ_REG_CLOCK_SPI
);
359 clk
->parent
= parent
;
364 static int jz_clk_i2s_set_parent(struct clk
*clk
, struct clk
*parent
)
366 if (parent
== &jz_clk_pll_half
)
367 jz_clk_reg_set_bits(JZ_REG_CLOCK_CTRL
, JZ_CLOCK_CTRL_I2S_SRC_PLL
);
368 else if(parent
== &jz_clk_ext
.clk
)
369 jz_clk_reg_clear_bits(JZ_REG_CLOCK_CTRL
, JZ_CLOCK_CTRL_I2S_SRC_PLL
);
373 clk
->parent
= parent
;
378 static int jz_clk_udc_set_parent(struct clk
*clk
, struct clk
*parent
)
380 if (parent
== &jz_clk_pll_half
)
381 jz_clk_reg_set_bits(JZ_REG_CLOCK_CTRL
, JZ_CLOCK_CTRL_UDC_SRC_PLL
);
382 else if(parent
== &jz_clk_ext
.clk
)
383 jz_clk_reg_clear_bits(JZ_REG_CLOCK_CTRL
, JZ_CLOCK_CTRL_UDC_SRC_PLL
);
387 clk
->parent
= parent
;
392 static int jz_clk_udc_set_rate(struct clk
*clk
, unsigned long rate
)
396 if (clk
->parent
== &jz_clk_ext
.clk
)
399 div
= clk_get_rate(clk
->parent
) / rate
- 1;
406 jz_clk_reg_write_mask(JZ_REG_CLOCK_CTRL
, div
<< JZ_CLOCK_CTRL_UDIV_OFFSET
,
407 JZ_CLOCK_CTRL_UDIV_MASK
);
411 static unsigned long jz_clk_udc_get_rate(struct clk
*clk
)
415 if (clk
->parent
== &jz_clk_ext
.clk
)
416 return clk_get_rate(clk
->parent
);
418 div
= (jz_clk_reg_read(JZ_REG_CLOCK_CTRL
) & JZ_CLOCK_CTRL_UDIV_MASK
);
419 div
>>= JZ_CLOCK_CTRL_UDIV_OFFSET
;
422 return clk_get_rate(clk
->parent
) / div
;
425 static unsigned long jz_clk_divided_get_rate(struct clk
*clk
)
427 struct divided_clk
*dclk
= (struct divided_clk
*)clk
;
430 if (clk
->parent
== &jz_clk_ext
.clk
)
431 return clk_get_rate(clk
->parent
);
433 div
= (jz_clk_reg_read(dclk
->reg
) & dclk
->mask
) + 1;
435 return clk_get_rate(clk
->parent
) / div
;
438 static int jz_clk_divided_set_rate(struct clk
*clk
, unsigned long rate
)
440 struct divided_clk
*dclk
= (struct divided_clk
*)clk
;
443 if (clk
->parent
== &jz_clk_ext
.clk
)
446 div
= clk_get_rate(clk
->parent
) / rate
- 1;
450 else if(div
> dclk
->mask
)
453 jz_clk_reg_write_mask(dclk
->reg
, div
, dclk
->mask
);
458 static unsigned long jz_clk_ldclk_round_rate(struct clk
*clk
, unsigned long rate
)
461 unsigned long parent_rate
= jz_clk_pll_half_get_rate(clk
->parent
);
463 if (rate
> 150000000)
466 div
= parent_rate
/ rate
;
472 return parent_rate
/ div
;
475 static int jz_clk_ldclk_set_rate(struct clk
*clk
, unsigned long rate
)
479 if (rate
> 150000000)
482 div
= jz_clk_pll_half_get_rate(clk
->parent
) / rate
- 1;
488 jz_clk_reg_write_mask(JZ_REG_CLOCK_CTRL
, div
<< JZ_CLOCK_CTRL_LDIV_OFFSET
,
489 JZ_CLOCK_CTRL_LDIV_MASK
);
494 static unsigned long jz_clk_ldclk_get_rate(struct clk
*clk
)
498 div
= jz_clk_reg_read(JZ_REG_CLOCK_CTRL
) & JZ_CLOCK_CTRL_LDIV_MASK
;
499 div
>>= JZ_CLOCK_CTRL_LDIV_OFFSET
;
501 return jz_clk_pll_half_get_rate(clk
->parent
) / (div
+ 1);
504 static struct clk jz_clk_ld
= {
506 .parent
= &jz_clk_pll_half
,
507 .set_rate
= jz_clk_ldclk_set_rate
,
508 .get_rate
= jz_clk_ldclk_get_rate
,
509 .round_rate
= jz_clk_ldclk_round_rate
,
512 static struct divided_clk jz_clk_lp
= {
515 .parent
= &jz_clk_pll_half
,
517 .reg
= JZ_REG_CLOCK_LCD
,
518 .mask
= JZ_CLOCK_LCD_DIV_MASK
,
521 static struct clk jz_clk_cim_mclk
= {
523 .parent
= &jz_clk_high_speed_peripheral
.clk
,
526 static struct static_clk jz_clk_cim_pclk
= {
529 .gate_bit
= JZ_CLOCK_GATE_CIM
,
530 .get_rate
= jz_clk_static_get_rate
,
531 .enable
= jz_clk_enable_gating
,
532 .disable
= jz_clk_disable_gating
,
536 static struct divided_clk jz_clk_i2s
= {
539 .parent
= &jz_clk_ext
.clk
,
540 .gate_bit
= JZ_CLOCK_GATE_AIC
,
541 .set_rate
= jz_clk_divided_set_rate
,
542 .get_rate
= jz_clk_divided_get_rate
,
543 .enable
= jz_clk_enable_gating
,
544 .disable
= jz_clk_disable_gating
,
545 .set_parent
= jz_clk_i2s_set_parent
,
547 .reg
= JZ_REG_CLOCK_I2S
,
548 .mask
= JZ_CLOCK_I2S_DIV_MASK
,
551 static struct divided_clk jz_clk_mmc
= {
554 .parent
= &jz_clk_pll_half
,
555 .gate_bit
= JZ_CLOCK_GATE_MMC
,
556 .set_rate
= jz_clk_divided_set_rate
,
557 .get_rate
= jz_clk_divided_get_rate
,
558 .enable
= jz_clk_enable_gating
,
559 .disable
= jz_clk_disable_gating
,
561 .reg
= JZ_REG_CLOCK_MMC
,
562 .mask
= JZ_CLOCK_MMC_DIV_MASK
,
565 static struct divided_clk jz_clk_uhc
= {
568 .parent
= &jz_clk_pll_half
,
569 .gate_bit
= JZ_CLOCK_GATE_UHC
,
570 .set_rate
= jz_clk_divided_set_rate
,
571 .get_rate
= jz_clk_divided_get_rate
,
572 .enable
= jz_clk_enable_gating
,
573 .disable
= jz_clk_disable_gating
,
575 .reg
= JZ_REG_CLOCK_UHC
,
576 .mask
= JZ_CLOCK_UHC_DIV_MASK
,
579 static struct clk jz_clk_udc
= {
581 .parent
= &jz_clk_ext
.clk
,
582 .set_parent
= jz_clk_udc_set_parent
,
583 .set_rate
= jz_clk_udc_set_rate
,
584 .get_rate
= jz_clk_udc_get_rate
,
587 static struct divided_clk jz_clk_spi
= {
590 .parent
= &jz_clk_ext
.clk
,
591 .gate_bit
= JZ_CLOCK_GATE_SPI
,
592 .set_rate
= jz_clk_divided_set_rate
,
593 .get_rate
= jz_clk_divided_get_rate
,
594 .enable
= jz_clk_enable_gating
,
595 .disable
= jz_clk_disable_gating
,
596 .set_parent
= jz_clk_spi_set_parent
,
598 .reg
= JZ_REG_CLOCK_SPI
,
599 .mask
= JZ_CLOCK_SPI_DIV_MASK
,
602 static struct clk jz_clk_uart0
= {
604 .parent
= &jz_clk_ext
.clk
,
605 .gate_bit
= JZ_CLOCK_GATE_UART0
,
606 .enable
= jz_clk_enable_gating
,
607 .disable
= jz_clk_disable_gating
,
610 static struct clk jz_clk_uart1
= {
612 .parent
= &jz_clk_ext
.clk
,
613 .gate_bit
= JZ_CLOCK_GATE_UART1
,
614 .enable
= jz_clk_enable_gating
,
615 .disable
= jz_clk_disable_gating
,
618 static struct clk jz_clk_dma
= {
620 .parent
= &jz_clk_high_speed_peripheral
.clk
,
621 .gate_bit
= JZ_CLOCK_GATE_UART0
,
622 .enable
= jz_clk_enable_gating
,
623 .disable
= jz_clk_disable_gating
,
626 static struct clk jz_clk_ipu
= {
628 .parent
= &jz_clk_high_speed_peripheral
.clk
,
629 .gate_bit
= JZ_CLOCK_GATE_IPU
,
630 .enable
= jz_clk_enable_gating
,
631 .disable
= jz_clk_disable_gating
,
634 static struct clk jz_clk_adc
= {
636 .parent
= &jz_clk_ext
.clk
,
637 .gate_bit
= JZ_CLOCK_GATE_ADC
,
638 .enable
= jz_clk_enable_gating
,
639 .disable
= jz_clk_disable_gating
,
642 static struct clk jz_clk_i2c
= {
644 .parent
= &jz_clk_ext
.clk
,
645 .gate_bit
= JZ_CLOCK_GATE_I2C
,
646 .enable
= jz_clk_enable_gating
,
647 .disable
= jz_clk_disable_gating
,
650 static struct static_clk jz_clk_rtc
= {
653 .gate_bit
= JZ_CLOCK_GATE_RTC
,
654 .enable
= jz_clk_enable_gating
,
655 .disable
= jz_clk_disable_gating
,
660 int clk_enable(struct clk
*clk
)
665 return clk
->enable(clk
);
667 EXPORT_SYMBOL_GPL(clk_enable
);
669 void clk_disable(struct clk
*clk
)
674 EXPORT_SYMBOL_GPL(clk_disable
);
676 unsigned long clk_get_rate(struct clk
*clk
)
679 return clk
->get_rate(clk
);
681 return clk_get_rate(clk
->parent
);
685 EXPORT_SYMBOL_GPL(clk_get_rate
);
687 int clk_set_rate(struct clk
*clk
, unsigned long rate
)
691 return clk
->set_rate(clk
, rate
);
693 EXPORT_SYMBOL_GPL(clk_set_rate
);
695 long clk_round_rate(struct clk
*clk
, unsigned long rate
)
698 return clk
->round_rate(clk
, rate
);
702 EXPORT_SYMBOL_GPL(clk_round_rate
);
704 int clk_set_parent(struct clk
*clk
, struct clk
*parent
)
708 if (!clk
->set_parent
)
712 ret
= clk
->set_parent(clk
, parent
);
717 EXPORT_SYMBOL_GPL(clk_set_parent
);
720 struct clk
*clk_get(struct device
*dev
, const char *name
)
724 list_for_each_entry(clk
, &jz_clocks
, list
) {
725 if (strcmp(clk
->name
, name
) == 0)
728 return ERR_PTR(-ENOENT
);
730 EXPORT_SYMBOL_GPL(clk_get
);
732 void clk_put(struct clk
*clk
)
735 EXPORT_SYMBOL_GPL(clk_put
);
737 inline static void clk_add(struct clk
*clk
)
739 list_add_tail(&clk
->list
, &jz_clocks
);
742 static void clk_register_clks(void)
744 clk_add(&jz_clk_ext
.clk
);
745 clk_add(&jz_clk_pll
);
746 clk_add(&jz_clk_pll_half
);
747 clk_add(&jz_clk_cpu
.clk
);
748 clk_add(&jz_clk_high_speed_peripheral
.clk
);
749 clk_add(&jz_clk_low_speed_peripheral
.clk
);
752 clk_add(&jz_clk_lp
.clk
);
753 clk_add(&jz_clk_cim_mclk
);
754 clk_add(&jz_clk_cim_pclk
.clk
);
755 clk_add(&jz_clk_i2s
.clk
);
756 clk_add(&jz_clk_mmc
.clk
);
757 clk_add(&jz_clk_uhc
.clk
);
758 clk_add(&jz_clk_udc
);
759 clk_add(&jz_clk_uart0
);
760 clk_add(&jz_clk_uart1
);
761 clk_add(&jz_clk_dma
);
762 clk_add(&jz_clk_ipu
);
763 clk_add(&jz_clk_adc
);
764 clk_add(&jz_clk_i2c
);
765 clk_add(&jz_clk_rtc
.clk
);
768 int jz_init_clocks(unsigned long ext_rate
)
772 jz_clock_base
= ioremap(0x10000000, 0x100);
776 jz_clk_ext
.rate
= ext_rate
;
778 val
= jz_clk_reg_read(JZ_REG_CLOCK_SPI
);
780 if (val
& JZ_CLOCK_SPI_SRC_PLL
)
781 jz_clk_spi
.clk
.parent
= &jz_clk_pll_half
;
783 val
= jz_clk_reg_read(JZ_REG_CLOCK_CTRL
);
785 if (val
& JZ_CLOCK_CTRL_I2S_SRC_PLL
)
786 jz_clk_i2s
.clk
.parent
= &jz_clk_pll_half
;
788 if (val
& JZ_CLOCK_CTRL_UDC_SRC_PLL
)
789 jz_clk_udc
.parent
= &jz_clk_pll_half
;
795 EXPORT_SYMBOL_GPL(jz_init_clocks
);