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 unsigned long xtal;
36 static struct clksrc_clk clk_mout_apll = {
41 .sources = &clk_src_apll,
42 .reg_src = { .reg = S5P_CLK_SRC0, .shift = 0, .size = 1 },
45 static struct clksrc_clk clk_mout_epll = {
50 .sources = &clk_src_epll,
51 .reg_src = { .reg = S5P_CLK_SRC0, .shift = 8, .size = 1 },
54 static struct clksrc_clk clk_mout_mpll = {
59 .sources = &clk_src_mpll,
60 .reg_src = { .reg = S5P_CLK_SRC0, .shift = 4, .size = 1 },
63 static struct clk *clkset_armclk_list[] = {
64 [0] = &clk_mout_apll.clk,
65 [1] = &clk_mout_mpll.clk,
68 static struct clksrc_sources clkset_armclk = {
69 .sources = clkset_armclk_list,
70 .nr_sources = ARRAY_SIZE(clkset_armclk_list),
73 static struct clksrc_clk clk_armclk = {
78 .sources = &clkset_armclk,
79 .reg_src = { .reg = S5P_CLK_SRC0, .shift = 16, .size = 1 },
80 .reg_div = { .reg = S5P_CLK_DIV0, .shift = 0, .size = 3 },
83 static struct clksrc_clk clk_hclk_msys = {
87 .parent = &clk_armclk.clk,
89 .reg_div = { .reg = S5P_CLK_DIV0, .shift = 8, .size = 3 },
92 static struct clksrc_clk clk_pclk_msys = {
96 .parent = &clk_hclk_msys.clk,
98 .reg_div = { .reg = S5P_CLK_DIV0, .shift = 12, .size = 3 },
101 static struct clksrc_clk clk_sclk_a2m = {
105 .parent = &clk_mout_apll.clk,
107 .reg_div = { .reg = S5P_CLK_DIV0, .shift = 4, .size = 3 },
110 static struct clk *clkset_hclk_sys_list[] = {
111 [0] = &clk_mout_mpll.clk,
112 [1] = &clk_sclk_a2m.clk,
115 static struct clksrc_sources clkset_hclk_sys = {
116 .sources = clkset_hclk_sys_list,
117 .nr_sources = ARRAY_SIZE(clkset_hclk_sys_list),
120 static struct clksrc_clk clk_hclk_dsys = {
125 .sources = &clkset_hclk_sys,
126 .reg_src = { .reg = S5P_CLK_SRC0, .shift = 20, .size = 1 },
127 .reg_div = { .reg = S5P_CLK_DIV0, .shift = 16, .size = 4 },
130 static struct clksrc_clk clk_pclk_dsys = {
134 .parent = &clk_hclk_dsys.clk,
136 .reg_div = { .reg = S5P_CLK_DIV0, .shift = 20, .size = 3 },
139 static struct clksrc_clk clk_hclk_psys = {
144 .sources = &clkset_hclk_sys,
145 .reg_src = { .reg = S5P_CLK_SRC0, .shift = 24, .size = 1 },
146 .reg_div = { .reg = S5P_CLK_DIV0, .shift = 24, .size = 4 },
149 static struct clksrc_clk clk_pclk_psys = {
153 .parent = &clk_hclk_psys.clk,
155 .reg_div = { .reg = S5P_CLK_DIV0, .shift = 28, .size = 3 },
158 static int s5pv210_clk_ip0_ctrl(struct clk *clk, int enable)
160 return s5p_gatectrl(S5P_CLKGATE_IP0, clk, enable);
163 static int s5pv210_clk_ip1_ctrl(struct clk *clk, int enable)
165 return s5p_gatectrl(S5P_CLKGATE_IP1, clk, enable);
168 static int s5pv210_clk_ip2_ctrl(struct clk *clk, int enable)
170 return s5p_gatectrl(S5P_CLKGATE_IP2, clk, enable);
173 static int s5pv210_clk_ip3_ctrl(struct clk *clk, int enable)
175 return s5p_gatectrl(S5P_CLKGATE_IP3, clk, enable);
178 static int s5pv210_clk_mask0_ctrl(struct clk *clk, int enable)
180 return s5p_gatectrl(S5P_CLK_SRC_MASK0, clk, enable);
183 static int s5pv210_clk_mask1_ctrl(struct clk *clk, int enable)
185 return s5p_gatectrl(S5P_CLK_SRC_MASK1, clk, enable);
188 static struct clk clk_sclk_hdmi27m = {
189 .name = "sclk_hdmi27m",
194 static struct clk clk_sclk_hdmiphy = {
195 .name = "sclk_hdmiphy",
199 static struct clk clk_sclk_usbphy0 = {
200 .name = "sclk_usbphy0",
204 static struct clk clk_sclk_usbphy1 = {
205 .name = "sclk_usbphy1",
209 static struct clk clk_pcmcdclk0 = {
214 static struct clk clk_pcmcdclk1 = {
219 static struct clk clk_pcmcdclk2 = {
224 static struct clk *clkset_vpllsrc_list[] = {
226 [1] = &clk_sclk_hdmi27m,
229 static struct clksrc_sources clkset_vpllsrc = {
230 .sources = clkset_vpllsrc_list,
231 .nr_sources = ARRAY_SIZE(clkset_vpllsrc_list),
234 static struct clksrc_clk clk_vpllsrc = {
238 .enable = s5pv210_clk_mask0_ctrl,
241 .sources = &clkset_vpllsrc,
242 .reg_src = { .reg = S5P_CLK_SRC1, .shift = 28, .size = 1 },
245 static struct clk *clkset_sclk_vpll_list[] = {
246 [0] = &clk_vpllsrc.clk,
247 [1] = &clk_fout_vpll,
250 static struct clksrc_sources clkset_sclk_vpll = {
251 .sources = clkset_sclk_vpll_list,
252 .nr_sources = ARRAY_SIZE(clkset_sclk_vpll_list),
255 static struct clksrc_clk clk_sclk_vpll = {
260 .sources = &clkset_sclk_vpll,
261 .reg_src = { .reg = S5P_CLK_SRC0, .shift = 12, .size = 1 },
264 static struct clk *clkset_moutdmc0src_list[] = {
265 [0] = &clk_sclk_a2m.clk,
266 [1] = &clk_mout_mpll.clk,
271 static struct clksrc_sources clkset_moutdmc0src = {
272 .sources = clkset_moutdmc0src_list,
273 .nr_sources = ARRAY_SIZE(clkset_moutdmc0src_list),
276 static struct clksrc_clk clk_mout_dmc0 = {
281 .sources = &clkset_moutdmc0src,
282 .reg_src = { .reg = S5P_CLK_SRC6, .shift = 24, .size = 2 },
285 static struct clksrc_clk clk_sclk_dmc0 = {
289 .parent = &clk_mout_dmc0.clk,
291 .reg_div = { .reg = S5P_CLK_DIV6, .shift = 28, .size = 4 },
294 static unsigned long s5pv210_clk_imem_get_rate(struct clk *clk)
296 return clk_get_rate(clk->parent) / 2;
299 static struct clk_ops clk_hclk_imem_ops = {
300 .get_rate = s5pv210_clk_imem_get_rate,
303 static unsigned long s5pv210_clk_fout_apll_get_rate(struct clk *clk)
305 return s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON), pll_4508);
308 static struct clk_ops clk_fout_apll_ops = {
309 .get_rate = s5pv210_clk_fout_apll_get_rate,
312 static struct clk init_clocks_disable[] = {
316 .parent = &clk_hclk_dsys.clk,
317 .enable = s5pv210_clk_ip0_ctrl,
322 .parent = &clk_hclk_dsys.clk,
323 .enable = s5pv210_clk_ip0_ctrl,
324 .ctrlbit = (1 << 24),
328 .parent = &clk_hclk_dsys.clk,
329 .enable = s5pv210_clk_ip0_ctrl,
330 .ctrlbit = (1 << 25),
334 .parent = &clk_hclk_dsys.clk,
335 .enable = s5pv210_clk_ip0_ctrl,
336 .ctrlbit = (1 << 26),
340 .parent = &clk_hclk_psys.clk,
341 .enable = s5pv210_clk_ip1_ctrl,
346 .parent = &clk_hclk_psys.clk,
347 .enable = s5pv210_clk_ip1_ctrl,
352 .parent = &clk_hclk_dsys.clk,
353 .enable = s5pv210_clk_ip1_ctrl,
358 .parent = &clk_hclk_psys.clk,
359 .enable = s5pv210_clk_ip1_ctrl,
364 .parent = &clk_hclk_psys.clk,
365 .enable = s5pv210_clk_ip2_ctrl,
370 .parent = &clk_hclk_psys.clk,
371 .enable = s5pv210_clk_ip2_ctrl,
376 .parent = &clk_hclk_psys.clk,
377 .enable = s5pv210_clk_ip2_ctrl,
382 .parent = &clk_hclk_psys.clk,
383 .enable = s5pv210_clk_ip2_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,
414 .ctrlbit = (1 << 10),
418 .parent = &clk_pclk_psys.clk,
419 .enable = s5pv210_clk_ip3_ctrl,
424 .parent = &clk_pclk_psys.clk,
425 .enable = s5pv210_clk_ip3_ctrl,
430 .parent = &clk_pclk_psys.clk,
431 .enable = s5pv210_clk_ip3_ctrl,
436 .parent = &clk_pclk_psys.clk,
437 .enable = s5pv210_clk_ip3_ctrl,
442 .parent = &clk_pclk_psys.clk,
443 .enable = s5pv210_clk_ip3_ctrl,
448 .parent = &clk_pclk_psys.clk,
449 .enable = s5pv210_clk_ip3_ctrl,
454 .parent = &clk_pclk_psys.clk,
455 .enable = s5pv210_clk_ip3_ctrl,
461 .enable = s5pv210_clk_ip3_ctrl,
467 .enable = s5pv210_clk_ip3_ctrl,
473 .enable = s5pv210_clk_ip3_ctrl,
478 static struct clk init_clocks[] = {
482 .parent = &clk_hclk_msys.clk,
484 .enable = s5pv210_clk_ip0_ctrl,
485 .ops = &clk_hclk_imem_ops,
489 .parent = &clk_pclk_psys.clk,
490 .enable = s5pv210_clk_ip3_ctrl,
491 .ctrlbit = (1 << 17),
495 .parent = &clk_pclk_psys.clk,
496 .enable = s5pv210_clk_ip3_ctrl,
497 .ctrlbit = (1 << 18),
501 .parent = &clk_pclk_psys.clk,
502 .enable = s5pv210_clk_ip3_ctrl,
503 .ctrlbit = (1 << 19),
507 .parent = &clk_pclk_psys.clk,
508 .enable = s5pv210_clk_ip3_ctrl,
509 .ctrlbit = (1 << 20),
513 static struct clk *clkset_uart_list[] = {
514 [6] = &clk_mout_mpll.clk,
515 [7] = &clk_mout_epll.clk,
518 static struct clksrc_sources clkset_uart = {
519 .sources = clkset_uart_list,
520 .nr_sources = ARRAY_SIZE(clkset_uart_list),
523 static struct clk *clkset_group1_list[] = {
524 [0] = &clk_sclk_a2m.clk,
525 [1] = &clk_mout_mpll.clk,
526 [2] = &clk_mout_epll.clk,
527 [3] = &clk_sclk_vpll.clk,
530 static struct clksrc_sources clkset_group1 = {
531 .sources = clkset_group1_list,
532 .nr_sources = ARRAY_SIZE(clkset_group1_list),
535 static struct clk *clkset_sclk_onenand_list[] = {
536 [0] = &clk_hclk_psys.clk,
537 [1] = &clk_hclk_dsys.clk,
540 static struct clksrc_sources clkset_sclk_onenand = {
541 .sources = clkset_sclk_onenand_list,
542 .nr_sources = ARRAY_SIZE(clkset_sclk_onenand_list),
545 static struct clk *clkset_sclk_dac_list[] = {
546 [0] = &clk_sclk_vpll.clk,
547 [1] = &clk_sclk_hdmiphy,
550 static struct clksrc_sources clkset_sclk_dac = {
551 .sources = clkset_sclk_dac_list,
552 .nr_sources = ARRAY_SIZE(clkset_sclk_dac_list),
555 static struct clksrc_clk clk_sclk_dac = {
559 .enable = s5pv210_clk_mask0_ctrl,
562 .sources = &clkset_sclk_dac,
563 .reg_src = { .reg = S5P_CLK_SRC1, .shift = 8, .size = 1 },
566 static struct clksrc_clk clk_sclk_pixel = {
568 .name = "sclk_pixel",
570 .parent = &clk_sclk_vpll.clk,
572 .reg_div = { .reg = S5P_CLK_DIV1, .shift = 0, .size = 4},
575 static struct clk *clkset_sclk_hdmi_list[] = {
576 [0] = &clk_sclk_pixel.clk,
577 [1] = &clk_sclk_hdmiphy,
580 static struct clksrc_sources clkset_sclk_hdmi = {
581 .sources = clkset_sclk_hdmi_list,
582 .nr_sources = ARRAY_SIZE(clkset_sclk_hdmi_list),
585 static struct clksrc_clk clk_sclk_hdmi = {
589 .enable = s5pv210_clk_mask0_ctrl,
592 .sources = &clkset_sclk_hdmi,
593 .reg_src = { .reg = S5P_CLK_SRC1, .shift = 0, .size = 1 },
596 static struct clk *clkset_sclk_mixer_list[] = {
597 [0] = &clk_sclk_dac.clk,
598 [1] = &clk_sclk_hdmi.clk,
601 static struct clksrc_sources clkset_sclk_mixer = {
602 .sources = clkset_sclk_mixer_list,
603 .nr_sources = ARRAY_SIZE(clkset_sclk_mixer_list),
606 static struct clk *clkset_sclk_audio0_list[] = {
607 [0] = &clk_ext_xtal_mux,
608 [1] = &clk_pcmcdclk0,
609 [2] = &clk_sclk_hdmi27m,
610 [3] = &clk_sclk_usbphy0,
611 [4] = &clk_sclk_usbphy1,
612 [5] = &clk_sclk_hdmiphy,
613 [6] = &clk_mout_mpll.clk,
614 [7] = &clk_mout_epll.clk,
615 [8] = &clk_sclk_vpll.clk,
618 static struct clksrc_sources clkset_sclk_audio0 = {
619 .sources = clkset_sclk_audio0_list,
620 .nr_sources = ARRAY_SIZE(clkset_sclk_audio0_list),
623 static struct clksrc_clk clk_sclk_audio0 = {
625 .name = "sclk_audio",
627 .enable = s5pv210_clk_mask0_ctrl,
628 .ctrlbit = (1 << 24),
630 .sources = &clkset_sclk_audio0,
631 .reg_src = { .reg = S5P_CLK_SRC6, .shift = 0, .size = 4 },
632 .reg_div = { .reg = S5P_CLK_DIV6, .shift = 0, .size = 4 },
635 static struct clk *clkset_sclk_audio1_list[] = {
636 [0] = &clk_ext_xtal_mux,
637 [1] = &clk_pcmcdclk1,
638 [2] = &clk_sclk_hdmi27m,
639 [3] = &clk_sclk_usbphy0,
640 [4] = &clk_sclk_usbphy1,
641 [5] = &clk_sclk_hdmiphy,
642 [6] = &clk_mout_mpll.clk,
643 [7] = &clk_mout_epll.clk,
644 [8] = &clk_sclk_vpll.clk,
647 static struct clksrc_sources clkset_sclk_audio1 = {
648 .sources = clkset_sclk_audio1_list,
649 .nr_sources = ARRAY_SIZE(clkset_sclk_audio1_list),
652 static struct clksrc_clk clk_sclk_audio1 = {
654 .name = "sclk_audio",
656 .enable = s5pv210_clk_mask0_ctrl,
657 .ctrlbit = (1 << 25),
659 .sources = &clkset_sclk_audio1,
660 .reg_src = { .reg = S5P_CLK_SRC6, .shift = 4, .size = 4 },
661 .reg_div = { .reg = S5P_CLK_DIV6, .shift = 4, .size = 4 },
664 static struct clk *clkset_sclk_audio2_list[] = {
665 [0] = &clk_ext_xtal_mux,
666 [1] = &clk_pcmcdclk0,
667 [2] = &clk_sclk_hdmi27m,
668 [3] = &clk_sclk_usbphy0,
669 [4] = &clk_sclk_usbphy1,
670 [5] = &clk_sclk_hdmiphy,
671 [6] = &clk_mout_mpll.clk,
672 [7] = &clk_mout_epll.clk,
673 [8] = &clk_sclk_vpll.clk,
676 static struct clksrc_sources clkset_sclk_audio2 = {
677 .sources = clkset_sclk_audio2_list,
678 .nr_sources = ARRAY_SIZE(clkset_sclk_audio2_list),
681 static struct clksrc_clk clk_sclk_audio2 = {
683 .name = "sclk_audio",
685 .enable = s5pv210_clk_mask0_ctrl,
686 .ctrlbit = (1 << 26),
688 .sources = &clkset_sclk_audio2,
689 .reg_src = { .reg = S5P_CLK_SRC6, .shift = 8, .size = 4 },
690 .reg_div = { .reg = S5P_CLK_DIV6, .shift = 8, .size = 4 },
693 static struct clk *clkset_sclk_spdif_list[] = {
694 [0] = &clk_sclk_audio0.clk,
695 [1] = &clk_sclk_audio1.clk,
696 [2] = &clk_sclk_audio2.clk,
699 static struct clksrc_sources clkset_sclk_spdif = {
700 .sources = clkset_sclk_spdif_list,
701 .nr_sources = ARRAY_SIZE(clkset_sclk_spdif_list),
704 static struct clk *clkset_group2_list[] = {
705 [0] = &clk_ext_xtal_mux,
707 [2] = &clk_sclk_hdmi27m,
708 [3] = &clk_sclk_usbphy0,
709 [4] = &clk_sclk_usbphy1,
710 [5] = &clk_sclk_hdmiphy,
711 [6] = &clk_mout_mpll.clk,
712 [7] = &clk_mout_epll.clk,
713 [8] = &clk_sclk_vpll.clk,
716 static struct clksrc_sources clkset_group2 = {
717 .sources = clkset_group2_list,
718 .nr_sources = ARRAY_SIZE(clkset_group2_list),
721 static struct clksrc_clk clksrcs[] = {
727 .sources = &clkset_group1,
728 .reg_src = { .reg = S5P_CLK_SRC6, .shift = 24, .size = 2 },
729 .reg_div = { .reg = S5P_CLK_DIV6, .shift = 28, .size = 4 },
732 .name = "sclk_onenand",
735 .sources = &clkset_sclk_onenand,
736 .reg_src = { .reg = S5P_CLK_SRC0, .shift = 28, .size = 1 },
737 .reg_div = { .reg = S5P_CLK_DIV6, .shift = 12, .size = 3 },
742 .enable = s5pv210_clk_mask0_ctrl,
743 .ctrlbit = (1 << 12),
745 .sources = &clkset_uart,
746 .reg_src = { .reg = S5P_CLK_SRC4, .shift = 16, .size = 4 },
747 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 16, .size = 4 },
752 .enable = s5pv210_clk_mask0_ctrl,
753 .ctrlbit = (1 << 13),
755 .sources = &clkset_uart,
756 .reg_src = { .reg = S5P_CLK_SRC4, .shift = 20, .size = 4 },
757 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 20, .size = 4 },
762 .enable = s5pv210_clk_mask0_ctrl,
763 .ctrlbit = (1 << 14),
765 .sources = &clkset_uart,
766 .reg_src = { .reg = S5P_CLK_SRC4, .shift = 24, .size = 4 },
767 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 24, .size = 4 },
772 .enable = s5pv210_clk_mask0_ctrl,
773 .ctrlbit = (1 << 15),
775 .sources = &clkset_uart,
776 .reg_src = { .reg = S5P_CLK_SRC4, .shift = 28, .size = 4 },
777 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 28, .size = 4 },
780 .name = "sclk_mixer",
782 .enable = s5pv210_clk_mask0_ctrl,
785 .sources = &clkset_sclk_mixer,
786 .reg_src = { .reg = S5P_CLK_SRC1, .shift = 4, .size = 1 },
789 .name = "sclk_spdif",
791 .enable = s5pv210_clk_mask0_ctrl,
792 .ctrlbit = (1 << 27),
794 .sources = &clkset_sclk_spdif,
795 .reg_src = { .reg = S5P_CLK_SRC6, .shift = 12, .size = 2 },
800 .enable = s5pv210_clk_mask1_ctrl,
803 .sources = &clkset_group2,
804 .reg_src = { .reg = S5P_CLK_SRC3, .shift = 12, .size = 4 },
805 .reg_div = { .reg = S5P_CLK_DIV3, .shift = 12, .size = 4 },
810 .enable = s5pv210_clk_mask1_ctrl,
813 .sources = &clkset_group2,
814 .reg_src = { .reg = S5P_CLK_SRC3, .shift = 16, .size = 4 },
815 .reg_div = { .reg = S5P_CLK_DIV3, .shift = 16, .size = 4 },
820 .enable = s5pv210_clk_mask1_ctrl,
823 .sources = &clkset_group2,
824 .reg_src = { .reg = S5P_CLK_SRC3, .shift = 20, .size = 4 },
825 .reg_div = { .reg = S5P_CLK_DIV3, .shift = 20, .size = 4 },
830 .enable = s5pv210_clk_mask0_ctrl,
833 .sources = &clkset_group2,
834 .reg_src = { .reg = S5P_CLK_SRC1, .shift = 12, .size = 4 },
835 .reg_div = { .reg = S5P_CLK_DIV1, .shift = 12, .size = 4 },
840 .enable = s5pv210_clk_mask0_ctrl,
843 .sources = &clkset_group2,
844 .reg_src = { .reg = S5P_CLK_SRC1, .shift = 16, .size = 4 },
845 .reg_div = { .reg = S5P_CLK_DIV1, .shift = 16, .size = 4 },
850 .enable = s5pv210_clk_mask0_ctrl,
853 .sources = &clkset_group2,
854 .reg_src = { .reg = S5P_CLK_SRC1, .shift = 20, .size = 4 },
855 .reg_div = { .reg = S5P_CLK_DIV1, .shift = 20, .size = 4 },
860 .enable = s5pv210_clk_mask0_ctrl,
863 .sources = &clkset_group2,
864 .reg_src = { .reg = S5P_CLK_SRC4, .shift = 0, .size = 4 },
865 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 0, .size = 4 },
870 .enable = s5pv210_clk_mask0_ctrl,
873 .sources = &clkset_group2,
874 .reg_src = { .reg = S5P_CLK_SRC4, .shift = 4, .size = 4 },
875 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 4, .size = 4 },
880 .enable = s5pv210_clk_mask0_ctrl,
881 .ctrlbit = (1 << 10),
883 .sources = &clkset_group2,
884 .reg_src = { .reg = S5P_CLK_SRC4, .shift = 8, .size = 4 },
885 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 8, .size = 4 },
890 .enable = s5pv210_clk_mask0_ctrl,
891 .ctrlbit = (1 << 11),
893 .sources = &clkset_group2,
894 .reg_src = { .reg = S5P_CLK_SRC4, .shift = 12, .size = 4 },
895 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 12, .size = 4 },
900 .enable = s5pv210_clk_ip0_ctrl,
901 .ctrlbit = (1 << 16),
903 .sources = &clkset_group1,
904 .reg_src = { .reg = S5P_CLK_SRC2, .shift = 4, .size = 2 },
905 .reg_div = { .reg = S5P_CLK_DIV2, .shift = 4, .size = 4 },
910 .enable = s5pv210_clk_ip0_ctrl,
911 .ctrlbit = (1 << 12),
913 .sources = &clkset_group1,
914 .reg_src = { .reg = S5P_CLK_SRC2, .shift = 8, .size = 2 },
915 .reg_div = { .reg = S5P_CLK_DIV2, .shift = 8, .size = 4 },
920 .enable = s5pv210_clk_ip0_ctrl,
923 .sources = &clkset_group1,
924 .reg_src = { .reg = S5P_CLK_SRC2, .shift = 0, .size = 2 },
925 .reg_div = { .reg = S5P_CLK_DIV2, .shift = 0, .size = 4 },
930 .enable = s5pv210_clk_mask0_ctrl,
933 .sources = &clkset_group2,
934 .reg_src = { .reg = S5P_CLK_SRC1, .shift = 24, .size = 4 },
935 .reg_div = { .reg = S5P_CLK_DIV1, .shift = 28, .size = 4 },
940 .enable = s5pv210_clk_mask0_ctrl,
941 .ctrlbit = (1 << 16),
943 .sources = &clkset_group2,
944 .reg_src = { .reg = S5P_CLK_SRC5, .shift = 0, .size = 4 },
945 .reg_div = { .reg = S5P_CLK_DIV5, .shift = 0, .size = 4 },
950 .enable = s5pv210_clk_mask0_ctrl,
951 .ctrlbit = (1 << 17),
953 .sources = &clkset_group2,
954 .reg_src = { .reg = S5P_CLK_SRC5, .shift = 4, .size = 4 },
955 .reg_div = { .reg = S5P_CLK_DIV5, .shift = 4, .size = 4 },
960 .enable = s5pv210_clk_mask0_ctrl,
961 .ctrlbit = (1 << 29),
963 .sources = &clkset_group2,
964 .reg_src = { .reg = S5P_CLK_SRC6, .shift = 20, .size = 4 },
965 .reg_div = { .reg = S5P_CLK_DIV6, .shift = 24, .size = 4 },
970 .enable = s5pv210_clk_mask0_ctrl,
971 .ctrlbit = (1 << 19),
973 .sources = &clkset_group2,
974 .reg_src = { .reg = S5P_CLK_SRC5, .shift = 12, .size = 4 },
975 .reg_div = { .reg = S5P_CLK_DIV5, .shift = 12, .size = 4 },
979 /* Clock initialisation code */
980 static struct clksrc_clk *sysclks[] = {
1001 void __init_or_cpufreq s5pv210_setup_clocks(void)
1003 struct clk *xtal_clk;
1004 unsigned long vpllsrc;
1005 unsigned long armclk;
1006 unsigned long hclk_msys;
1007 unsigned long hclk_dsys;
1008 unsigned long hclk_psys;
1009 unsigned long pclk_msys;
1010 unsigned long pclk_dsys;
1011 unsigned long pclk_psys;
1017 u32 clkdiv0, clkdiv1;
1019 printk(KERN_DEBUG "%s: registering clocks\n", __func__);
1021 clkdiv0 = __raw_readl(S5P_CLK_DIV0);
1022 clkdiv1 = __raw_readl(S5P_CLK_DIV1);
1024 printk(KERN_DEBUG "%s: clkdiv0 = %08x, clkdiv1 = %08x\n",
1025 __func__, clkdiv0, clkdiv1);
1027 xtal_clk = clk_get(NULL, "xtal");
1028 BUG_ON(IS_ERR(xtal_clk));
1030 xtal = clk_get_rate(xtal_clk);
1033 printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal);
1035 apll = s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON), pll_4508);
1036 mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P_MPLL_CON), pll_4502);
1037 epll = s5p_get_pll45xx(xtal, __raw_readl(S5P_EPLL_CON), pll_4500);
1038 vpllsrc = clk_get_rate(&clk_vpllsrc.clk);
1039 vpll = s5p_get_pll45xx(vpllsrc, __raw_readl(S5P_VPLL_CON), pll_4502);
1041 clk_fout_apll.ops = &clk_fout_apll_ops;
1042 clk_fout_mpll.rate = mpll;
1043 clk_fout_epll.rate = epll;
1044 clk_fout_vpll.rate = vpll;
1046 printk(KERN_INFO "S5PV210: PLL settings, A=%ld, M=%ld, E=%ld V=%ld",
1047 apll, mpll, epll, vpll);
1049 armclk = clk_get_rate(&clk_armclk.clk);
1050 hclk_msys = clk_get_rate(&clk_hclk_msys.clk);
1051 hclk_dsys = clk_get_rate(&clk_hclk_dsys.clk);
1052 hclk_psys = clk_get_rate(&clk_hclk_psys.clk);
1053 pclk_msys = clk_get_rate(&clk_pclk_msys.clk);
1054 pclk_dsys = clk_get_rate(&clk_pclk_dsys.clk);
1055 pclk_psys = clk_get_rate(&clk_pclk_psys.clk);
1057 printk(KERN_INFO "S5PV210: ARMCLK=%ld, HCLKM=%ld, HCLKD=%ld\n"
1058 "HCLKP=%ld, PCLKM=%ld, PCLKD=%ld, PCLKP=%ld\n",
1059 armclk, hclk_msys, hclk_dsys, hclk_psys,
1060 pclk_msys, pclk_dsys, pclk_psys);
1062 clk_f.rate = armclk;
1063 clk_h.rate = hclk_psys;
1064 clk_p.rate = pclk_psys;
1066 for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
1067 s3c_set_clksrc(&clksrcs[ptr], true);
1070 static struct clk *clks[] __initdata = {
1080 void __init s5pv210_register_clocks(void)
1086 ret = s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
1088 printk(KERN_ERR "Failed to register %u clocks\n", ret);
1090 for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++)
1091 s3c_register_clksrc(sysclks[ptr], 1);
1093 s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
1094 s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
1096 clkp = init_clocks_disable;
1097 for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) {
1098 ret = s3c24xx_register_clock(clkp);
1100 printk(KERN_ERR "Failed to register clock %s (%d)\n",
1103 (clkp->enable)(clkp, 0);