1 /* linux/arch/arm/mach-s5pv210/clock.c
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
6 * S5PV210 - Clock support
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
13 #include <linux/init.h>
14 #include <linux/module.h>
15 #include <linux/kernel.h>
16 #include <linux/list.h>
17 #include <linux/errno.h>
18 #include <linux/err.h>
19 #include <linux/clk.h>
20 #include <linux/sysdev.h>
25 #include <plat/cpu-freq.h>
26 #include <mach/regs-clock.h>
27 #include <plat/clock.h>
30 #include <plat/s5p-clock.h>
31 #include <plat/clock-clksrc.h>
32 #include <plat/s5pv210.h>
34 static struct clksrc_clk clk_mout_apll
= {
39 .sources
= &clk_src_apll
,
40 .reg_src
= { .reg
= S5P_CLK_SRC0
, .shift
= 0, .size
= 1 },
43 static struct clksrc_clk clk_mout_epll
= {
48 .sources
= &clk_src_epll
,
49 .reg_src
= { .reg
= S5P_CLK_SRC0
, .shift
= 8, .size
= 1 },
52 static struct clksrc_clk clk_mout_mpll
= {
57 .sources
= &clk_src_mpll
,
58 .reg_src
= { .reg
= S5P_CLK_SRC0
, .shift
= 4, .size
= 1 },
61 static struct clk
*clkset_armclk_list
[] = {
62 [0] = &clk_mout_apll
.clk
,
63 [1] = &clk_mout_mpll
.clk
,
66 static struct clksrc_sources clkset_armclk
= {
67 .sources
= clkset_armclk_list
,
68 .nr_sources
= ARRAY_SIZE(clkset_armclk_list
),
71 static struct clksrc_clk clk_armclk
= {
76 .sources
= &clkset_armclk
,
77 .reg_src
= { .reg
= S5P_CLK_SRC0
, .shift
= 16, .size
= 1 },
78 .reg_div
= { .reg
= S5P_CLK_DIV0
, .shift
= 0, .size
= 3 },
81 static struct clksrc_clk clk_hclk_msys
= {
85 .parent
= &clk_armclk
.clk
,
87 .reg_div
= { .reg
= S5P_CLK_DIV0
, .shift
= 8, .size
= 3 },
90 static struct clksrc_clk clk_pclk_msys
= {
94 .parent
= &clk_hclk_msys
.clk
,
96 .reg_div
= { .reg
= S5P_CLK_DIV0
, .shift
= 12, .size
= 3 },
99 static struct clksrc_clk clk_sclk_a2m
= {
103 .parent
= &clk_mout_apll
.clk
,
105 .reg_div
= { .reg
= S5P_CLK_DIV0
, .shift
= 4, .size
= 3 },
108 static struct clk
*clkset_hclk_sys_list
[] = {
109 [0] = &clk_mout_mpll
.clk
,
110 [1] = &clk_sclk_a2m
.clk
,
113 static struct clksrc_sources clkset_hclk_sys
= {
114 .sources
= clkset_hclk_sys_list
,
115 .nr_sources
= ARRAY_SIZE(clkset_hclk_sys_list
),
118 static struct clksrc_clk clk_hclk_dsys
= {
123 .sources
= &clkset_hclk_sys
,
124 .reg_src
= { .reg
= S5P_CLK_SRC0
, .shift
= 20, .size
= 1 },
125 .reg_div
= { .reg
= S5P_CLK_DIV0
, .shift
= 16, .size
= 4 },
128 static struct clksrc_clk clk_pclk_dsys
= {
132 .parent
= &clk_hclk_dsys
.clk
,
134 .reg_div
= { .reg
= S5P_CLK_DIV0
, .shift
= 20, .size
= 3 },
137 static struct clksrc_clk clk_hclk_psys
= {
142 .sources
= &clkset_hclk_sys
,
143 .reg_src
= { .reg
= S5P_CLK_SRC0
, .shift
= 24, .size
= 1 },
144 .reg_div
= { .reg
= S5P_CLK_DIV0
, .shift
= 24, .size
= 4 },
147 static struct clksrc_clk clk_pclk_psys
= {
151 .parent
= &clk_hclk_psys
.clk
,
153 .reg_div
= { .reg
= S5P_CLK_DIV0
, .shift
= 28, .size
= 3 },
156 static int s5pv210_clk_ip0_ctrl(struct clk
*clk
, int enable
)
158 return s5p_gatectrl(S5P_CLKGATE_IP0
, clk
, enable
);
161 static int s5pv210_clk_ip1_ctrl(struct clk
*clk
, int enable
)
163 return s5p_gatectrl(S5P_CLKGATE_IP1
, clk
, enable
);
166 static int s5pv210_clk_ip2_ctrl(struct clk
*clk
, int enable
)
168 return s5p_gatectrl(S5P_CLKGATE_IP2
, clk
, enable
);
171 static int s5pv210_clk_ip3_ctrl(struct clk
*clk
, int enable
)
173 return s5p_gatectrl(S5P_CLKGATE_IP3
, clk
, enable
);
176 static int s5pv210_clk_ip4_ctrl(struct clk
*clk
, int enable
)
178 return s5p_gatectrl(S5P_CLKGATE_IP4
, clk
, enable
);
181 static int s5pv210_clk_mask0_ctrl(struct clk
*clk
, int enable
)
183 return s5p_gatectrl(S5P_CLK_SRC_MASK0
, clk
, enable
);
186 static int s5pv210_clk_mask1_ctrl(struct clk
*clk
, int enable
)
188 return s5p_gatectrl(S5P_CLK_SRC_MASK1
, clk
, enable
);
191 static struct clk clk_sclk_hdmi27m
= {
192 .name
= "sclk_hdmi27m",
197 static struct clk clk_sclk_hdmiphy
= {
198 .name
= "sclk_hdmiphy",
202 static struct clk clk_sclk_usbphy0
= {
203 .name
= "sclk_usbphy0",
207 static struct clk clk_sclk_usbphy1
= {
208 .name
= "sclk_usbphy1",
212 static struct clk clk_pcmcdclk0
= {
217 static struct clk clk_pcmcdclk1
= {
222 static struct clk clk_pcmcdclk2
= {
227 static struct clk
*clkset_vpllsrc_list
[] = {
229 [1] = &clk_sclk_hdmi27m
,
232 static struct clksrc_sources clkset_vpllsrc
= {
233 .sources
= clkset_vpllsrc_list
,
234 .nr_sources
= ARRAY_SIZE(clkset_vpllsrc_list
),
237 static struct clksrc_clk clk_vpllsrc
= {
241 .enable
= s5pv210_clk_mask0_ctrl
,
244 .sources
= &clkset_vpllsrc
,
245 .reg_src
= { .reg
= S5P_CLK_SRC1
, .shift
= 28, .size
= 1 },
248 static struct clk
*clkset_sclk_vpll_list
[] = {
249 [0] = &clk_vpllsrc
.clk
,
250 [1] = &clk_fout_vpll
,
253 static struct clksrc_sources clkset_sclk_vpll
= {
254 .sources
= clkset_sclk_vpll_list
,
255 .nr_sources
= ARRAY_SIZE(clkset_sclk_vpll_list
),
258 static struct clksrc_clk clk_sclk_vpll
= {
263 .sources
= &clkset_sclk_vpll
,
264 .reg_src
= { .reg
= S5P_CLK_SRC0
, .shift
= 12, .size
= 1 },
267 static unsigned long s5pv210_clk_imem_get_rate(struct clk
*clk
)
269 return clk_get_rate(clk
->parent
) / 2;
272 static struct clk_ops clk_hclk_imem_ops
= {
273 .get_rate
= s5pv210_clk_imem_get_rate
,
276 static struct clk init_clocks_disable
[] = {
280 .parent
= &clk_hclk_dsys
.clk
,
281 .enable
= s5pv210_clk_ip0_ctrl
,
286 .parent
= &clk_hclk_dsys
.clk
,
287 .enable
= s5pv210_clk_ip0_ctrl
,
288 .ctrlbit
= (1 << 24),
292 .parent
= &clk_hclk_dsys
.clk
,
293 .enable
= s5pv210_clk_ip0_ctrl
,
294 .ctrlbit
= (1 << 25),
298 .parent
= &clk_hclk_dsys
.clk
,
299 .enable
= s5pv210_clk_ip0_ctrl
,
300 .ctrlbit
= (1 << 26),
304 .parent
= &clk_hclk_psys
.clk
,
305 .enable
= s5pv210_clk_ip1_ctrl
,
310 .parent
= &clk_hclk_psys
.clk
,
311 .enable
= s5pv210_clk_ip1_ctrl
,
316 .parent
= &clk_hclk_dsys
.clk
,
317 .enable
= s5pv210_clk_ip1_ctrl
,
322 .parent
= &clk_hclk_psys
.clk
,
323 .enable
= s5pv210_clk_ip1_ctrl
,
328 .parent
= &clk_hclk_psys
.clk
,
329 .enable
= s5pv210_clk_ip2_ctrl
,
334 .parent
= &clk_hclk_psys
.clk
,
335 .enable
= s5pv210_clk_ip2_ctrl
,
340 .parent
= &clk_hclk_psys
.clk
,
341 .enable
= s5pv210_clk_ip2_ctrl
,
346 .parent
= &clk_hclk_psys
.clk
,
347 .enable
= s5pv210_clk_ip2_ctrl
,
352 .parent
= &clk_pclk_psys
.clk
,
353 .enable
= s5pv210_clk_ip3_ctrl
,
358 .parent
= &clk_pclk_psys
.clk
,
359 .enable
= s5pv210_clk_ip3_ctrl
,
364 .parent
= &clk_pclk_psys
.clk
,
365 .enable
= s5pv210_clk_ip3_ctrl
,
370 .parent
= &clk_pclk_psys
.clk
,
371 .enable
= s5pv210_clk_ip3_ctrl
,
376 .parent
= &clk_pclk_psys
.clk
,
377 .enable
= s5pv210_clk_ip3_ctrl
,
378 .ctrlbit
= (1 << 10),
382 .parent
= &clk_pclk_psys
.clk
,
383 .enable
= s5pv210_clk_ip3_ctrl
,
388 .parent
= &clk_pclk_psys
.clk
,
389 .enable
= s5pv210_clk_ip3_ctrl
,
394 .parent
= &clk_pclk_psys
.clk
,
395 .enable
= s5pv210_clk_ip3_ctrl
,
400 .parent
= &clk_pclk_psys
.clk
,
401 .enable
= s5pv210_clk_ip3_ctrl
,
406 .parent
= &clk_pclk_psys
.clk
,
407 .enable
= s5pv210_clk_ip3_ctrl
,
412 .parent
= &clk_pclk_psys
.clk
,
413 .enable
= s5pv210_clk_ip3_ctrl
,
418 .parent
= &clk_pclk_psys
.clk
,
419 .enable
= s5pv210_clk_ip3_ctrl
,
425 .enable
= s5pv210_clk_ip3_ctrl
,
431 .enable
= s5pv210_clk_ip3_ctrl
,
437 .enable
= s5pv210_clk_ip3_ctrl
,
442 static struct clk init_clocks
[] = {
446 .parent
= &clk_hclk_msys
.clk
,
448 .enable
= s5pv210_clk_ip0_ctrl
,
449 .ops
= &clk_hclk_imem_ops
,
453 .parent
= &clk_pclk_psys
.clk
,
454 .enable
= s5pv210_clk_ip3_ctrl
,
455 .ctrlbit
= (1 << 17),
459 .parent
= &clk_pclk_psys
.clk
,
460 .enable
= s5pv210_clk_ip3_ctrl
,
461 .ctrlbit
= (1 << 18),
465 .parent
= &clk_pclk_psys
.clk
,
466 .enable
= s5pv210_clk_ip3_ctrl
,
467 .ctrlbit
= (1 << 19),
471 .parent
= &clk_pclk_psys
.clk
,
472 .enable
= s5pv210_clk_ip3_ctrl
,
473 .ctrlbit
= (1 << 20),
477 static struct clk
*clkset_uart_list
[] = {
478 [6] = &clk_mout_mpll
.clk
,
479 [7] = &clk_mout_epll
.clk
,
482 static struct clksrc_sources clkset_uart
= {
483 .sources
= clkset_uart_list
,
484 .nr_sources
= ARRAY_SIZE(clkset_uart_list
),
487 static struct clk
*clkset_group1_list
[] = {
488 [0] = &clk_sclk_a2m
.clk
,
489 [1] = &clk_mout_mpll
.clk
,
490 [2] = &clk_mout_epll
.clk
,
491 [3] = &clk_sclk_vpll
.clk
,
494 static struct clksrc_sources clkset_group1
= {
495 .sources
= clkset_group1_list
,
496 .nr_sources
= ARRAY_SIZE(clkset_group1_list
),
499 static struct clk
*clkset_sclk_onenand_list
[] = {
500 [0] = &clk_hclk_psys
.clk
,
501 [1] = &clk_hclk_dsys
.clk
,
504 static struct clksrc_sources clkset_sclk_onenand
= {
505 .sources
= clkset_sclk_onenand_list
,
506 .nr_sources
= ARRAY_SIZE(clkset_sclk_onenand_list
),
509 static struct clk
*clkset_sclk_dac_list
[] = {
510 [0] = &clk_sclk_vpll
.clk
,
511 [1] = &clk_sclk_hdmiphy
,
514 static struct clksrc_sources clkset_sclk_dac
= {
515 .sources
= clkset_sclk_dac_list
,
516 .nr_sources
= ARRAY_SIZE(clkset_sclk_dac_list
),
519 static struct clksrc_clk clk_sclk_dac
= {
523 .enable
= s5pv210_clk_mask0_ctrl
,
526 .sources
= &clkset_sclk_dac
,
527 .reg_src
= { .reg
= S5P_CLK_SRC1
, .shift
= 8, .size
= 1 },
530 static struct clksrc_clk clk_sclk_pixel
= {
532 .name
= "sclk_pixel",
534 .parent
= &clk_sclk_vpll
.clk
,
536 .reg_div
= { .reg
= S5P_CLK_DIV1
, .shift
= 0, .size
= 4},
539 static struct clk
*clkset_sclk_hdmi_list
[] = {
540 [0] = &clk_sclk_pixel
.clk
,
541 [1] = &clk_sclk_hdmiphy
,
544 static struct clksrc_sources clkset_sclk_hdmi
= {
545 .sources
= clkset_sclk_hdmi_list
,
546 .nr_sources
= ARRAY_SIZE(clkset_sclk_hdmi_list
),
549 static struct clksrc_clk clk_sclk_hdmi
= {
553 .enable
= s5pv210_clk_mask0_ctrl
,
556 .sources
= &clkset_sclk_hdmi
,
557 .reg_src
= { .reg
= S5P_CLK_SRC1
, .shift
= 0, .size
= 1 },
560 static struct clk
*clkset_sclk_mixer_list
[] = {
561 [0] = &clk_sclk_dac
.clk
,
562 [1] = &clk_sclk_hdmi
.clk
,
565 static struct clksrc_sources clkset_sclk_mixer
= {
566 .sources
= clkset_sclk_mixer_list
,
567 .nr_sources
= ARRAY_SIZE(clkset_sclk_mixer_list
),
570 static struct clk
*clkset_sclk_audio0_list
[] = {
571 [0] = &clk_ext_xtal_mux
,
572 [1] = &clk_pcmcdclk0
,
573 [2] = &clk_sclk_hdmi27m
,
574 [3] = &clk_sclk_usbphy0
,
575 [4] = &clk_sclk_usbphy1
,
576 [5] = &clk_sclk_hdmiphy
,
577 [6] = &clk_mout_mpll
.clk
,
578 [7] = &clk_mout_epll
.clk
,
579 [8] = &clk_sclk_vpll
.clk
,
582 static struct clksrc_sources clkset_sclk_audio0
= {
583 .sources
= clkset_sclk_audio0_list
,
584 .nr_sources
= ARRAY_SIZE(clkset_sclk_audio0_list
),
587 static struct clksrc_clk clk_sclk_audio0
= {
589 .name
= "sclk_audio",
591 .enable
= s5pv210_clk_mask0_ctrl
,
592 .ctrlbit
= (1 << 24),
594 .sources
= &clkset_sclk_audio0
,
595 .reg_src
= { .reg
= S5P_CLK_SRC6
, .shift
= 0, .size
= 4 },
596 .reg_div
= { .reg
= S5P_CLK_DIV6
, .shift
= 0, .size
= 4 },
599 static struct clk
*clkset_sclk_audio1_list
[] = {
600 [0] = &clk_ext_xtal_mux
,
601 [1] = &clk_pcmcdclk1
,
602 [2] = &clk_sclk_hdmi27m
,
603 [3] = &clk_sclk_usbphy0
,
604 [4] = &clk_sclk_usbphy1
,
605 [5] = &clk_sclk_hdmiphy
,
606 [6] = &clk_mout_mpll
.clk
,
607 [7] = &clk_mout_epll
.clk
,
608 [8] = &clk_sclk_vpll
.clk
,
611 static struct clksrc_sources clkset_sclk_audio1
= {
612 .sources
= clkset_sclk_audio1_list
,
613 .nr_sources
= ARRAY_SIZE(clkset_sclk_audio1_list
),
616 static struct clksrc_clk clk_sclk_audio1
= {
618 .name
= "sclk_audio",
620 .enable
= s5pv210_clk_mask0_ctrl
,
621 .ctrlbit
= (1 << 25),
623 .sources
= &clkset_sclk_audio1
,
624 .reg_src
= { .reg
= S5P_CLK_SRC6
, .shift
= 4, .size
= 4 },
625 .reg_div
= { .reg
= S5P_CLK_DIV6
, .shift
= 4, .size
= 4 },
628 static struct clk
*clkset_sclk_audio2_list
[] = {
629 [0] = &clk_ext_xtal_mux
,
630 [1] = &clk_pcmcdclk0
,
631 [2] = &clk_sclk_hdmi27m
,
632 [3] = &clk_sclk_usbphy0
,
633 [4] = &clk_sclk_usbphy1
,
634 [5] = &clk_sclk_hdmiphy
,
635 [6] = &clk_mout_mpll
.clk
,
636 [7] = &clk_mout_epll
.clk
,
637 [8] = &clk_sclk_vpll
.clk
,
640 static struct clksrc_sources clkset_sclk_audio2
= {
641 .sources
= clkset_sclk_audio2_list
,
642 .nr_sources
= ARRAY_SIZE(clkset_sclk_audio2_list
),
645 static struct clksrc_clk clk_sclk_audio2
= {
647 .name
= "sclk_audio",
649 .enable
= s5pv210_clk_mask0_ctrl
,
650 .ctrlbit
= (1 << 26),
652 .sources
= &clkset_sclk_audio2
,
653 .reg_src
= { .reg
= S5P_CLK_SRC6
, .shift
= 8, .size
= 4 },
654 .reg_div
= { .reg
= S5P_CLK_DIV6
, .shift
= 8, .size
= 4 },
657 static struct clk
*clkset_sclk_spdif_list
[] = {
658 [0] = &clk_sclk_audio0
.clk
,
659 [1] = &clk_sclk_audio1
.clk
,
660 [2] = &clk_sclk_audio2
.clk
,
663 static struct clksrc_sources clkset_sclk_spdif
= {
664 .sources
= clkset_sclk_spdif_list
,
665 .nr_sources
= ARRAY_SIZE(clkset_sclk_spdif_list
),
668 static struct clk
*clkset_group2_list
[] = {
669 [0] = &clk_ext_xtal_mux
,
671 [2] = &clk_sclk_hdmi27m
,
672 [3] = &clk_sclk_usbphy0
,
673 [4] = &clk_sclk_usbphy1
,
674 [5] = &clk_sclk_hdmiphy
,
675 [6] = &clk_mout_mpll
.clk
,
676 [7] = &clk_mout_epll
.clk
,
677 [8] = &clk_sclk_vpll
.clk
,
680 static struct clksrc_sources clkset_group2
= {
681 .sources
= clkset_group2_list
,
682 .nr_sources
= ARRAY_SIZE(clkset_group2_list
),
685 static struct clksrc_clk clksrcs
[] = {
691 .sources
= &clkset_group1
,
692 .reg_src
= { .reg
= S5P_CLK_SRC6
, .shift
= 24, .size
= 2 },
693 .reg_div
= { .reg
= S5P_CLK_DIV6
, .shift
= 28, .size
= 4 },
696 .name
= "sclk_onenand",
699 .sources
= &clkset_sclk_onenand
,
700 .reg_src
= { .reg
= S5P_CLK_SRC0
, .shift
= 28, .size
= 1 },
701 .reg_div
= { .reg
= S5P_CLK_DIV6
, .shift
= 12, .size
= 3 },
706 .enable
= s5pv210_clk_mask0_ctrl
,
707 .ctrlbit
= (1 << 12),
709 .sources
= &clkset_uart
,
710 .reg_src
= { .reg
= S5P_CLK_SRC4
, .shift
= 16, .size
= 4 },
711 .reg_div
= { .reg
= S5P_CLK_DIV4
, .shift
= 16, .size
= 4 },
716 .enable
= s5pv210_clk_mask0_ctrl
,
717 .ctrlbit
= (1 << 13),
719 .sources
= &clkset_uart
,
720 .reg_src
= { .reg
= S5P_CLK_SRC4
, .shift
= 20, .size
= 4 },
721 .reg_div
= { .reg
= S5P_CLK_DIV4
, .shift
= 20, .size
= 4 },
726 .enable
= s5pv210_clk_mask0_ctrl
,
727 .ctrlbit
= (1 << 14),
729 .sources
= &clkset_uart
,
730 .reg_src
= { .reg
= S5P_CLK_SRC4
, .shift
= 24, .size
= 4 },
731 .reg_div
= { .reg
= S5P_CLK_DIV4
, .shift
= 24, .size
= 4 },
736 .enable
= s5pv210_clk_mask0_ctrl
,
737 .ctrlbit
= (1 << 15),
739 .sources
= &clkset_uart
,
740 .reg_src
= { .reg
= S5P_CLK_SRC4
, .shift
= 28, .size
= 4 },
741 .reg_div
= { .reg
= S5P_CLK_DIV4
, .shift
= 28, .size
= 4 },
744 .name
= "sclk_mixer",
746 .enable
= s5pv210_clk_mask0_ctrl
,
749 .sources
= &clkset_sclk_mixer
,
750 .reg_src
= { .reg
= S5P_CLK_SRC1
, .shift
= 4, .size
= 1 },
753 .name
= "sclk_spdif",
755 .enable
= s5pv210_clk_mask0_ctrl
,
756 .ctrlbit
= (1 << 27),
758 .sources
= &clkset_sclk_spdif
,
759 .reg_src
= { .reg
= S5P_CLK_SRC6
, .shift
= 12, .size
= 2 },
764 .enable
= s5pv210_clk_mask1_ctrl
,
767 .sources
= &clkset_group2
,
768 .reg_src
= { .reg
= S5P_CLK_SRC3
, .shift
= 12, .size
= 4 },
769 .reg_div
= { .reg
= S5P_CLK_DIV3
, .shift
= 12, .size
= 4 },
774 .enable
= s5pv210_clk_mask1_ctrl
,
777 .sources
= &clkset_group2
,
778 .reg_src
= { .reg
= S5P_CLK_SRC3
, .shift
= 16, .size
= 4 },
779 .reg_div
= { .reg
= S5P_CLK_DIV3
, .shift
= 16, .size
= 4 },
784 .enable
= s5pv210_clk_mask1_ctrl
,
787 .sources
= &clkset_group2
,
788 .reg_src
= { .reg
= S5P_CLK_SRC3
, .shift
= 20, .size
= 4 },
789 .reg_div
= { .reg
= S5P_CLK_DIV3
, .shift
= 20, .size
= 4 },
794 .enable
= s5pv210_clk_mask0_ctrl
,
797 .sources
= &clkset_group2
,
798 .reg_src
= { .reg
= S5P_CLK_SRC1
, .shift
= 12, .size
= 4 },
799 .reg_div
= { .reg
= S5P_CLK_DIV1
, .shift
= 12, .size
= 4 },
804 .enable
= s5pv210_clk_mask0_ctrl
,
807 .sources
= &clkset_group2
,
808 .reg_src
= { .reg
= S5P_CLK_SRC1
, .shift
= 16, .size
= 4 },
809 .reg_div
= { .reg
= S5P_CLK_DIV1
, .shift
= 16, .size
= 4 },
814 .enable
= s5pv210_clk_mask0_ctrl
,
817 .sources
= &clkset_group2
,
818 .reg_src
= { .reg
= S5P_CLK_SRC1
, .shift
= 20, .size
= 4 },
819 .reg_div
= { .reg
= S5P_CLK_DIV1
, .shift
= 20, .size
= 4 },
824 .enable
= s5pv210_clk_mask0_ctrl
,
827 .sources
= &clkset_group2
,
828 .reg_src
= { .reg
= S5P_CLK_SRC4
, .shift
= 0, .size
= 4 },
829 .reg_div
= { .reg
= S5P_CLK_DIV4
, .shift
= 0, .size
= 4 },
834 .enable
= s5pv210_clk_mask0_ctrl
,
837 .sources
= &clkset_group2
,
838 .reg_src
= { .reg
= S5P_CLK_SRC4
, .shift
= 4, .size
= 4 },
839 .reg_div
= { .reg
= S5P_CLK_DIV4
, .shift
= 4, .size
= 4 },
844 .enable
= s5pv210_clk_mask0_ctrl
,
845 .ctrlbit
= (1 << 10),
847 .sources
= &clkset_group2
,
848 .reg_src
= { .reg
= S5P_CLK_SRC4
, .shift
= 8, .size
= 4 },
849 .reg_div
= { .reg
= S5P_CLK_DIV4
, .shift
= 8, .size
= 4 },
854 .enable
= s5pv210_clk_mask0_ctrl
,
855 .ctrlbit
= (1 << 11),
857 .sources
= &clkset_group2
,
858 .reg_src
= { .reg
= S5P_CLK_SRC4
, .shift
= 12, .size
= 4 },
859 .reg_div
= { .reg
= S5P_CLK_DIV4
, .shift
= 12, .size
= 4 },
864 .enable
= s5pv210_clk_ip0_ctrl
,
865 .ctrlbit
= (1 << 16),
867 .sources
= &clkset_group1
,
868 .reg_src
= { .reg
= S5P_CLK_SRC2
, .shift
= 4, .size
= 2 },
869 .reg_div
= { .reg
= S5P_CLK_DIV2
, .shift
= 4, .size
= 4 },
874 .enable
= s5pv210_clk_ip0_ctrl
,
875 .ctrlbit
= (1 << 12),
877 .sources
= &clkset_group1
,
878 .reg_src
= { .reg
= S5P_CLK_SRC2
, .shift
= 8, .size
= 2 },
879 .reg_div
= { .reg
= S5P_CLK_DIV2
, .shift
= 8, .size
= 4 },
884 .enable
= s5pv210_clk_ip0_ctrl
,
887 .sources
= &clkset_group1
,
888 .reg_src
= { .reg
= S5P_CLK_SRC2
, .shift
= 0, .size
= 2 },
889 .reg_div
= { .reg
= S5P_CLK_DIV2
, .shift
= 0, .size
= 4 },
894 .enable
= s5pv210_clk_mask0_ctrl
,
897 .sources
= &clkset_group2
,
898 .reg_src
= { .reg
= S5P_CLK_SRC1
, .shift
= 24, .size
= 4 },
899 .reg_div
= { .reg
= S5P_CLK_DIV1
, .shift
= 28, .size
= 4 },
904 .enable
= s5pv210_clk_mask0_ctrl
,
905 .ctrlbit
= (1 << 16),
907 .sources
= &clkset_group2
,
908 .reg_src
= { .reg
= S5P_CLK_SRC5
, .shift
= 0, .size
= 4 },
909 .reg_div
= { .reg
= S5P_CLK_DIV5
, .shift
= 0, .size
= 4 },
914 .enable
= s5pv210_clk_mask0_ctrl
,
915 .ctrlbit
= (1 << 17),
917 .sources
= &clkset_group2
,
918 .reg_src
= { .reg
= S5P_CLK_SRC5
, .shift
= 4, .size
= 4 },
919 .reg_div
= { .reg
= S5P_CLK_DIV5
, .shift
= 4, .size
= 4 },
924 .enable
= s5pv210_clk_mask0_ctrl
,
925 .ctrlbit
= (1 << 29),
927 .sources
= &clkset_group2
,
928 .reg_src
= { .reg
= S5P_CLK_SRC6
, .shift
= 20, .size
= 4 },
929 .reg_div
= { .reg
= S5P_CLK_DIV6
, .shift
= 24, .size
= 4 },
934 .enable
= s5pv210_clk_mask0_ctrl
,
935 .ctrlbit
= (1 << 19),
937 .sources
= &clkset_group2
,
938 .reg_src
= { .reg
= S5P_CLK_SRC5
, .shift
= 12, .size
= 4 },
939 .reg_div
= { .reg
= S5P_CLK_DIV5
, .shift
= 12, .size
= 4 },
943 /* Clock initialisation code */
944 static struct clksrc_clk
*sysclks
[] = {
963 void __init_or_cpufreq
s5pv210_setup_clocks(void)
965 struct clk
*xtal_clk
;
967 unsigned long vpllsrc
;
968 unsigned long armclk
;
969 unsigned long hclk_msys
;
970 unsigned long hclk_dsys
;
971 unsigned long hclk_psys
;
972 unsigned long pclk_msys
;
973 unsigned long pclk_dsys
;
974 unsigned long pclk_psys
;
980 u32 clkdiv0
, clkdiv1
;
982 printk(KERN_DEBUG
"%s: registering clocks\n", __func__
);
984 clkdiv0
= __raw_readl(S5P_CLK_DIV0
);
985 clkdiv1
= __raw_readl(S5P_CLK_DIV1
);
987 printk(KERN_DEBUG
"%s: clkdiv0 = %08x, clkdiv1 = %08x\n",
988 __func__
, clkdiv0
, clkdiv1
);
990 xtal_clk
= clk_get(NULL
, "xtal");
991 BUG_ON(IS_ERR(xtal_clk
));
993 xtal
= clk_get_rate(xtal_clk
);
996 printk(KERN_DEBUG
"%s: xtal is %ld\n", __func__
, xtal
);
998 apll
= s5p_get_pll45xx(xtal
, __raw_readl(S5P_APLL_CON
), pll_4508
);
999 mpll
= s5p_get_pll45xx(xtal
, __raw_readl(S5P_MPLL_CON
), pll_4502
);
1000 epll
= s5p_get_pll45xx(xtal
, __raw_readl(S5P_EPLL_CON
), pll_4500
);
1001 vpllsrc
= clk_get_rate(&clk_vpllsrc
.clk
);
1002 vpll
= s5p_get_pll45xx(vpllsrc
, __raw_readl(S5P_VPLL_CON
), pll_4502
);
1004 clk_fout_apll
.rate
= apll
;
1005 clk_fout_mpll
.rate
= mpll
;
1006 clk_fout_epll
.rate
= epll
;
1007 clk_fout_vpll
.rate
= vpll
;
1009 printk(KERN_INFO
"S5PV210: PLL settings, A=%ld, M=%ld, E=%ld V=%ld",
1010 apll
, mpll
, epll
, vpll
);
1012 armclk
= clk_get_rate(&clk_armclk
.clk
);
1013 hclk_msys
= clk_get_rate(&clk_hclk_msys
.clk
);
1014 hclk_dsys
= clk_get_rate(&clk_hclk_dsys
.clk
);
1015 hclk_psys
= clk_get_rate(&clk_hclk_psys
.clk
);
1016 pclk_msys
= clk_get_rate(&clk_pclk_msys
.clk
);
1017 pclk_dsys
= clk_get_rate(&clk_pclk_dsys
.clk
);
1018 pclk_psys
= clk_get_rate(&clk_pclk_psys
.clk
);
1020 printk(KERN_INFO
"S5PV210: ARMCLK=%ld, HCLKM=%ld, HCLKD=%ld\n"
1021 "HCLKP=%ld, PCLKM=%ld, PCLKD=%ld, PCLKP=%ld\n",
1022 armclk
, hclk_msys
, hclk_dsys
, hclk_psys
,
1023 pclk_msys
, pclk_dsys
, pclk_psys
);
1025 clk_f
.rate
= armclk
;
1026 clk_h
.rate
= hclk_psys
;
1027 clk_p
.rate
= pclk_psys
;
1029 for (ptr
= 0; ptr
< ARRAY_SIZE(clksrcs
); ptr
++)
1030 s3c_set_clksrc(&clksrcs
[ptr
], true);
1033 static struct clk
*clks
[] __initdata
= {
1043 void __init
s5pv210_register_clocks(void)
1049 ret
= s3c24xx_register_clocks(clks
, ARRAY_SIZE(clks
));
1051 printk(KERN_ERR
"Failed to register %u clocks\n", ret
);
1053 for (ptr
= 0; ptr
< ARRAY_SIZE(sysclks
); ptr
++)
1054 s3c_register_clksrc(sysclks
[ptr
], 1);
1056 s3c_register_clksrc(clksrcs
, ARRAY_SIZE(clksrcs
));
1057 s3c_register_clocks(init_clocks
, ARRAY_SIZE(init_clocks
));
1059 clkp
= init_clocks_disable
;
1060 for (ptr
= 0; ptr
< ARRAY_SIZE(init_clocks_disable
); ptr
++, clkp
++) {
1061 ret
= s3c24xx_register_clock(clkp
);
1063 printk(KERN_ERR
"Failed to register clock %s (%d)\n",
1066 (clkp
->enable
)(clkp
, 0);