1 /* linux/arch/arm/mach-exynos4/clock.c
3 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
6 * EXYNOS4 - 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/kernel.h>
14 #include <linux/err.h>
17 #include <plat/cpu-freq.h>
18 #include <plat/clock.h>
21 #include <plat/s5p-clock.h>
22 #include <plat/clock-clksrc.h>
25 #include <mach/regs-clock.h>
26 #include <mach/sysmmu.h>
28 static struct clk clk_sclk_hdmi27m = {
29 .name = "sclk_hdmi27m",
34 static struct clk clk_sclk_hdmiphy = {
35 .name = "sclk_hdmiphy",
39 static struct clk clk_sclk_usbphy0 = {
40 .name = "sclk_usbphy0",
45 static struct clk clk_sclk_usbphy1 = {
46 .name = "sclk_usbphy1",
50 static int exynos4_clksrc_mask_top_ctrl(struct clk *clk, int enable)
52 return s5p_gatectrl(S5P_CLKSRC_MASK_TOP, clk, enable);
55 static int exynos4_clksrc_mask_cam_ctrl(struct clk *clk, int enable)
57 return s5p_gatectrl(S5P_CLKSRC_MASK_CAM, clk, enable);
60 static int exynos4_clksrc_mask_lcd0_ctrl(struct clk *clk, int enable)
62 return s5p_gatectrl(S5P_CLKSRC_MASK_LCD0, clk, enable);
65 static int exynos4_clksrc_mask_lcd1_ctrl(struct clk *clk, int enable)
67 return s5p_gatectrl(S5P_CLKSRC_MASK_LCD1, clk, enable);
70 static int exynos4_clksrc_mask_fsys_ctrl(struct clk *clk, int enable)
72 return s5p_gatectrl(S5P_CLKSRC_MASK_FSYS, clk, enable);
75 static int exynos4_clksrc_mask_peril0_ctrl(struct clk *clk, int enable)
77 return s5p_gatectrl(S5P_CLKSRC_MASK_PERIL0, clk, enable);
80 static int exynos4_clksrc_mask_peril1_ctrl(struct clk *clk, int enable)
82 return s5p_gatectrl(S5P_CLKSRC_MASK_PERIL1, clk, enable);
85 static int exynos4_clk_ip_mfc_ctrl(struct clk *clk, int enable)
87 return s5p_gatectrl(S5P_CLKGATE_IP_MFC, clk, enable);
90 static int exynos4_clk_ip_cam_ctrl(struct clk *clk, int enable)
92 return s5p_gatectrl(S5P_CLKGATE_IP_CAM, clk, enable);
95 static int exynos4_clk_ip_tv_ctrl(struct clk *clk, int enable)
97 return s5p_gatectrl(S5P_CLKGATE_IP_TV, clk, enable);
100 static int exynos4_clk_ip_image_ctrl(struct clk *clk, int enable)
102 return s5p_gatectrl(S5P_CLKGATE_IP_IMAGE, clk, enable);
105 static int exynos4_clk_ip_lcd0_ctrl(struct clk *clk, int enable)
107 return s5p_gatectrl(S5P_CLKGATE_IP_LCD0, clk, enable);
110 static int exynos4_clk_ip_lcd1_ctrl(struct clk *clk, int enable)
112 return s5p_gatectrl(S5P_CLKGATE_IP_LCD1, clk, enable);
115 static int exynos4_clk_ip_fsys_ctrl(struct clk *clk, int enable)
117 return s5p_gatectrl(S5P_CLKGATE_IP_FSYS, clk, enable);
120 static int exynos4_clk_ip_peril_ctrl(struct clk *clk, int enable)
122 return s5p_gatectrl(S5P_CLKGATE_IP_PERIL, clk, enable);
125 static int exynos4_clk_ip_perir_ctrl(struct clk *clk, int enable)
127 return s5p_gatectrl(S5P_CLKGATE_IP_PERIR, clk, enable);
130 /* Core list of CMU_CPU side */
132 static struct clksrc_clk clk_mout_apll = {
137 .sources = &clk_src_apll,
138 .reg_src = { .reg = S5P_CLKSRC_CPU, .shift = 0, .size = 1 },
141 static struct clksrc_clk clk_sclk_apll = {
145 .parent = &clk_mout_apll.clk,
147 .reg_div = { .reg = S5P_CLKDIV_CPU, .shift = 24, .size = 3 },
150 static struct clksrc_clk clk_mout_epll = {
155 .sources = &clk_src_epll,
156 .reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 4, .size = 1 },
159 static struct clksrc_clk clk_mout_mpll = {
164 .sources = &clk_src_mpll,
165 .reg_src = { .reg = S5P_CLKSRC_CPU, .shift = 8, .size = 1 },
168 static struct clk *clkset_moutcore_list[] = {
169 [0] = &clk_mout_apll.clk,
170 [1] = &clk_mout_mpll.clk,
173 static struct clksrc_sources clkset_moutcore = {
174 .sources = clkset_moutcore_list,
175 .nr_sources = ARRAY_SIZE(clkset_moutcore_list),
178 static struct clksrc_clk clk_moutcore = {
183 .sources = &clkset_moutcore,
184 .reg_src = { .reg = S5P_CLKSRC_CPU, .shift = 16, .size = 1 },
187 static struct clksrc_clk clk_coreclk = {
191 .parent = &clk_moutcore.clk,
193 .reg_div = { .reg = S5P_CLKDIV_CPU, .shift = 0, .size = 3 },
196 static struct clksrc_clk clk_armclk = {
200 .parent = &clk_coreclk.clk,
204 static struct clksrc_clk clk_aclk_corem0 = {
206 .name = "aclk_corem0",
208 .parent = &clk_coreclk.clk,
210 .reg_div = { .reg = S5P_CLKDIV_CPU, .shift = 4, .size = 3 },
213 static struct clksrc_clk clk_aclk_cores = {
215 .name = "aclk_cores",
217 .parent = &clk_coreclk.clk,
219 .reg_div = { .reg = S5P_CLKDIV_CPU, .shift = 4, .size = 3 },
222 static struct clksrc_clk clk_aclk_corem1 = {
224 .name = "aclk_corem1",
226 .parent = &clk_coreclk.clk,
228 .reg_div = { .reg = S5P_CLKDIV_CPU, .shift = 8, .size = 3 },
231 static struct clksrc_clk clk_periphclk = {
235 .parent = &clk_coreclk.clk,
237 .reg_div = { .reg = S5P_CLKDIV_CPU, .shift = 12, .size = 3 },
240 /* Core list of CMU_CORE side */
242 static struct clk *clkset_corebus_list[] = {
243 [0] = &clk_mout_mpll.clk,
244 [1] = &clk_sclk_apll.clk,
247 static struct clksrc_sources clkset_mout_corebus = {
248 .sources = clkset_corebus_list,
249 .nr_sources = ARRAY_SIZE(clkset_corebus_list),
252 static struct clksrc_clk clk_mout_corebus = {
254 .name = "mout_corebus",
257 .sources = &clkset_mout_corebus,
258 .reg_src = { .reg = S5P_CLKSRC_DMC, .shift = 4, .size = 1 },
261 static struct clksrc_clk clk_sclk_dmc = {
265 .parent = &clk_mout_corebus.clk,
267 .reg_div = { .reg = S5P_CLKDIV_DMC0, .shift = 12, .size = 3 },
270 static struct clksrc_clk clk_aclk_cored = {
272 .name = "aclk_cored",
274 .parent = &clk_sclk_dmc.clk,
276 .reg_div = { .reg = S5P_CLKDIV_DMC0, .shift = 16, .size = 3 },
279 static struct clksrc_clk clk_aclk_corep = {
281 .name = "aclk_corep",
283 .parent = &clk_aclk_cored.clk,
285 .reg_div = { .reg = S5P_CLKDIV_DMC0, .shift = 20, .size = 3 },
288 static struct clksrc_clk clk_aclk_acp = {
292 .parent = &clk_mout_corebus.clk,
294 .reg_div = { .reg = S5P_CLKDIV_DMC0, .shift = 0, .size = 3 },
297 static struct clksrc_clk clk_pclk_acp = {
301 .parent = &clk_aclk_acp.clk,
303 .reg_div = { .reg = S5P_CLKDIV_DMC0, .shift = 4, .size = 3 },
306 /* Core list of CMU_TOP side */
308 static struct clk *clkset_aclk_top_list[] = {
309 [0] = &clk_mout_mpll.clk,
310 [1] = &clk_sclk_apll.clk,
313 static struct clksrc_sources clkset_aclk = {
314 .sources = clkset_aclk_top_list,
315 .nr_sources = ARRAY_SIZE(clkset_aclk_top_list),
318 static struct clksrc_clk clk_aclk_200 = {
323 .sources = &clkset_aclk,
324 .reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 12, .size = 1 },
325 .reg_div = { .reg = S5P_CLKDIV_TOP, .shift = 0, .size = 3 },
328 static struct clksrc_clk clk_aclk_100 = {
333 .sources = &clkset_aclk,
334 .reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 16, .size = 1 },
335 .reg_div = { .reg = S5P_CLKDIV_TOP, .shift = 4, .size = 4 },
338 static struct clksrc_clk clk_aclk_160 = {
343 .sources = &clkset_aclk,
344 .reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 20, .size = 1 },
345 .reg_div = { .reg = S5P_CLKDIV_TOP, .shift = 8, .size = 3 },
348 static struct clksrc_clk clk_aclk_133 = {
353 .sources = &clkset_aclk,
354 .reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 24, .size = 1 },
355 .reg_div = { .reg = S5P_CLKDIV_TOP, .shift = 12, .size = 3 },
358 static struct clk *clkset_vpllsrc_list[] = {
360 [1] = &clk_sclk_hdmi27m,
363 static struct clksrc_sources clkset_vpllsrc = {
364 .sources = clkset_vpllsrc_list,
365 .nr_sources = ARRAY_SIZE(clkset_vpllsrc_list),
368 static struct clksrc_clk clk_vpllsrc = {
372 .enable = exynos4_clksrc_mask_top_ctrl,
375 .sources = &clkset_vpllsrc,
376 .reg_src = { .reg = S5P_CLKSRC_TOP1, .shift = 0, .size = 1 },
379 static struct clk *clkset_sclk_vpll_list[] = {
380 [0] = &clk_vpllsrc.clk,
381 [1] = &clk_fout_vpll,
384 static struct clksrc_sources clkset_sclk_vpll = {
385 .sources = clkset_sclk_vpll_list,
386 .nr_sources = ARRAY_SIZE(clkset_sclk_vpll_list),
389 static struct clksrc_clk clk_sclk_vpll = {
394 .sources = &clkset_sclk_vpll,
395 .reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 8, .size = 1 },
398 static struct clk init_clocks_off[] = {
402 .parent = &clk_aclk_100.clk,
403 .enable = exynos4_clk_ip_peril_ctrl,
408 .enable = exynos4_clk_ip_cam_ctrl,
413 .enable = exynos4_clk_ip_cam_ctrl,
418 .enable = exynos4_clk_ip_cam_ctrl,
423 .enable = exynos4_clk_ip_cam_ctrl,
428 .enable = exynos4_clk_ip_cam_ctrl,
433 .enable = exynos4_clk_ip_cam_ctrl,
438 .enable = exynos4_clk_ip_lcd0_ctrl,
443 .enable = exynos4_clk_ip_lcd1_ctrl,
448 .parent = &clk_aclk_133.clk,
449 .enable = exynos4_clk_ip_fsys_ctrl,
454 .parent = &clk_aclk_133.clk,
455 .enable = exynos4_clk_ip_fsys_ctrl,
460 .parent = &clk_aclk_133.clk,
461 .enable = exynos4_clk_ip_fsys_ctrl,
466 .parent = &clk_aclk_133.clk,
467 .enable = exynos4_clk_ip_fsys_ctrl,
472 .parent = &clk_aclk_133.clk,
473 .enable = exynos4_clk_ip_fsys_ctrl,
478 .parent = &clk_aclk_133.clk,
479 .enable = exynos4_clk_ip_fsys_ctrl,
484 .parent = &clk_aclk_133.clk,
485 .enable = exynos4_clk_ip_fsys_ctrl,
486 .ctrlbit = (1 << 10),
490 .enable = exynos4_clk_ip_fsys_ctrl,
495 .enable = exynos4_clk_ip_fsys_ctrl,
500 .enable = exynos4_clk_ip_peril_ctrl,
501 .ctrlbit = (1 << 15),
505 .enable = exynos4_clk_ip_perir_ctrl,
506 .ctrlbit = (1 << 16),
510 .enable = exynos4_clk_ip_perir_ctrl,
511 .ctrlbit = (1 << 15),
515 .parent = &clk_aclk_100.clk,
516 .enable = exynos4_clk_ip_perir_ctrl,
517 .ctrlbit = (1 << 14),
521 .enable = exynos4_clk_ip_fsys_ctrl ,
522 .ctrlbit = (1 << 12),
526 .enable = exynos4_clk_ip_fsys_ctrl,
527 .ctrlbit = (1 << 13),
531 .enable = exynos4_clk_ip_peril_ctrl,
532 .ctrlbit = (1 << 16),
536 .enable = exynos4_clk_ip_peril_ctrl,
537 .ctrlbit = (1 << 17),
541 .enable = exynos4_clk_ip_peril_ctrl,
542 .ctrlbit = (1 << 18),
546 .enable = exynos4_clk_ip_peril_ctrl,
547 .ctrlbit = (1 << 19),
551 .enable = exynos4_clk_ip_peril_ctrl,
552 .ctrlbit = (1 << 20),
556 .enable = exynos4_clk_ip_peril_ctrl,
557 .ctrlbit = (1 << 21),
561 .enable = exynos4_clk_ip_peril_ctrl,
562 .ctrlbit = (1 << 27),
566 .enable = exynos4_clk_ip_image_ctrl,
571 .parent = &clk_aclk_100.clk,
572 .enable = exynos4_clk_ip_peril_ctrl,
577 .parent = &clk_aclk_100.clk,
578 .enable = exynos4_clk_ip_peril_ctrl,
583 .parent = &clk_aclk_100.clk,
584 .enable = exynos4_clk_ip_peril_ctrl,
589 .parent = &clk_aclk_100.clk,
590 .enable = exynos4_clk_ip_peril_ctrl,
595 .parent = &clk_aclk_100.clk,
596 .enable = exynos4_clk_ip_peril_ctrl,
597 .ctrlbit = (1 << 10),
601 .parent = &clk_aclk_100.clk,
602 .enable = exynos4_clk_ip_peril_ctrl,
603 .ctrlbit = (1 << 11),
607 .parent = &clk_aclk_100.clk,
608 .enable = exynos4_clk_ip_peril_ctrl,
609 .ctrlbit = (1 << 12),
613 .parent = &clk_aclk_100.clk,
614 .enable = exynos4_clk_ip_peril_ctrl,
615 .ctrlbit = (1 << 13),
617 .name = "SYSMMU_MDMA",
619 .enable = exynos4_clk_ip_image_ctrl,
622 .name = "SYSMMU_FIMC0",
624 .enable = exynos4_clk_ip_cam_ctrl,
627 .name = "SYSMMU_FIMC1",
629 .enable = exynos4_clk_ip_cam_ctrl,
632 .name = "SYSMMU_FIMC2",
634 .enable = exynos4_clk_ip_cam_ctrl,
637 .name = "SYSMMU_FIMC3",
639 .enable = exynos4_clk_ip_cam_ctrl,
640 .ctrlbit = (1 << 10),
642 .name = "SYSMMU_JPEG",
644 .enable = exynos4_clk_ip_cam_ctrl,
645 .ctrlbit = (1 << 11),
647 .name = "SYSMMU_FIMD0",
649 .enable = exynos4_clk_ip_lcd0_ctrl,
652 .name = "SYSMMU_FIMD1",
654 .enable = exynos4_clk_ip_lcd1_ctrl,
657 .name = "SYSMMU_PCIe",
659 .enable = exynos4_clk_ip_fsys_ctrl,
660 .ctrlbit = (1 << 18),
662 .name = "SYSMMU_G2D",
664 .enable = exynos4_clk_ip_image_ctrl,
667 .name = "SYSMMU_ROTATOR",
669 .enable = exynos4_clk_ip_image_ctrl,
674 .enable = exynos4_clk_ip_tv_ctrl,
677 .name = "SYSMMU_MFC_L",
679 .enable = exynos4_clk_ip_mfc_ctrl,
682 .name = "SYSMMU_MFC_R",
684 .enable = exynos4_clk_ip_mfc_ctrl,
689 static struct clk init_clocks[] = {
693 .enable = exynos4_clk_ip_peril_ctrl,
698 .enable = exynos4_clk_ip_peril_ctrl,
703 .enable = exynos4_clk_ip_peril_ctrl,
708 .enable = exynos4_clk_ip_peril_ctrl,
713 .enable = exynos4_clk_ip_peril_ctrl,
718 .enable = exynos4_clk_ip_peril_ctrl,
723 static struct clk *clkset_group_list[] = {
724 [0] = &clk_ext_xtal_mux,
726 [2] = &clk_sclk_hdmi27m,
727 [3] = &clk_sclk_usbphy0,
728 [4] = &clk_sclk_usbphy1,
729 [5] = &clk_sclk_hdmiphy,
730 [6] = &clk_mout_mpll.clk,
731 [7] = &clk_mout_epll.clk,
732 [8] = &clk_sclk_vpll.clk,
735 static struct clksrc_sources clkset_group = {
736 .sources = clkset_group_list,
737 .nr_sources = ARRAY_SIZE(clkset_group_list),
740 static struct clk *clkset_mout_g2d0_list[] = {
741 [0] = &clk_mout_mpll.clk,
742 [1] = &clk_sclk_apll.clk,
745 static struct clksrc_sources clkset_mout_g2d0 = {
746 .sources = clkset_mout_g2d0_list,
747 .nr_sources = ARRAY_SIZE(clkset_mout_g2d0_list),
750 static struct clksrc_clk clk_mout_g2d0 = {
755 .sources = &clkset_mout_g2d0,
756 .reg_src = { .reg = S5P_CLKSRC_IMAGE, .shift = 0, .size = 1 },
759 static struct clk *clkset_mout_g2d1_list[] = {
760 [0] = &clk_mout_epll.clk,
761 [1] = &clk_sclk_vpll.clk,
764 static struct clksrc_sources clkset_mout_g2d1 = {
765 .sources = clkset_mout_g2d1_list,
766 .nr_sources = ARRAY_SIZE(clkset_mout_g2d1_list),
769 static struct clksrc_clk clk_mout_g2d1 = {
774 .sources = &clkset_mout_g2d1,
775 .reg_src = { .reg = S5P_CLKSRC_IMAGE, .shift = 4, .size = 1 },
778 static struct clk *clkset_mout_g2d_list[] = {
779 [0] = &clk_mout_g2d0.clk,
780 [1] = &clk_mout_g2d1.clk,
783 static struct clksrc_sources clkset_mout_g2d = {
784 .sources = clkset_mout_g2d_list,
785 .nr_sources = ARRAY_SIZE(clkset_mout_g2d_list),
788 static struct clksrc_clk clk_dout_mmc0 = {
793 .sources = &clkset_group,
794 .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 0, .size = 4 },
795 .reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 0, .size = 4 },
798 static struct clksrc_clk clk_dout_mmc1 = {
803 .sources = &clkset_group,
804 .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 4, .size = 4 },
805 .reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 16, .size = 4 },
808 static struct clksrc_clk clk_dout_mmc2 = {
813 .sources = &clkset_group,
814 .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 8, .size = 4 },
815 .reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 0, .size = 4 },
818 static struct clksrc_clk clk_dout_mmc3 = {
823 .sources = &clkset_group,
824 .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 12, .size = 4 },
825 .reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 16, .size = 4 },
828 static struct clksrc_clk clk_dout_mmc4 = {
833 .sources = &clkset_group,
834 .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 16, .size = 4 },
835 .reg_div = { .reg = S5P_CLKDIV_FSYS3, .shift = 0, .size = 4 },
838 static struct clksrc_clk clksrcs[] = {
843 .enable = exynos4_clksrc_mask_peril0_ctrl,
846 .sources = &clkset_group,
847 .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 0, .size = 4 },
848 .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 0, .size = 4 },
853 .enable = exynos4_clksrc_mask_peril0_ctrl,
856 .sources = &clkset_group,
857 .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 4, .size = 4 },
858 .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 4, .size = 4 },
863 .enable = exynos4_clksrc_mask_peril0_ctrl,
866 .sources = &clkset_group,
867 .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 8, .size = 4 },
868 .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 8, .size = 4 },
873 .enable = exynos4_clksrc_mask_peril0_ctrl,
874 .ctrlbit = (1 << 12),
876 .sources = &clkset_group,
877 .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 12, .size = 4 },
878 .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 12, .size = 4 },
883 .enable = exynos4_clksrc_mask_peril0_ctrl,
884 .ctrlbit = (1 << 24),
886 .sources = &clkset_group,
887 .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 24, .size = 4 },
888 .reg_div = { .reg = S5P_CLKDIV_PERIL3, .shift = 0, .size = 4 },
893 .enable = exynos4_clksrc_mask_cam_ctrl,
894 .ctrlbit = (1 << 24),
896 .sources = &clkset_group,
897 .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 24, .size = 4 },
898 .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 24, .size = 4 },
903 .enable = exynos4_clksrc_mask_cam_ctrl,
904 .ctrlbit = (1 << 28),
906 .sources = &clkset_group,
907 .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 28, .size = 4 },
908 .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 28, .size = 4 },
913 .enable = exynos4_clksrc_mask_cam_ctrl,
914 .ctrlbit = (1 << 16),
916 .sources = &clkset_group,
917 .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 16, .size = 4 },
918 .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 16, .size = 4 },
923 .enable = exynos4_clksrc_mask_cam_ctrl,
924 .ctrlbit = (1 << 20),
926 .sources = &clkset_group,
927 .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 20, .size = 4 },
928 .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 20, .size = 4 },
933 .enable = exynos4_clksrc_mask_cam_ctrl,
936 .sources = &clkset_group,
937 .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 0, .size = 4 },
938 .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 0, .size = 4 },
943 .enable = exynos4_clksrc_mask_cam_ctrl,
946 .sources = &clkset_group,
947 .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 4, .size = 4 },
948 .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 4, .size = 4 },
953 .enable = exynos4_clksrc_mask_cam_ctrl,
956 .sources = &clkset_group,
957 .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 8, .size = 4 },
958 .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 8, .size = 4 },
963 .enable = exynos4_clksrc_mask_cam_ctrl,
964 .ctrlbit = (1 << 12),
966 .sources = &clkset_group,
967 .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 12, .size = 4 },
968 .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 12, .size = 4 },
973 .enable = exynos4_clksrc_mask_lcd0_ctrl,
976 .sources = &clkset_group,
977 .reg_src = { .reg = S5P_CLKSRC_LCD0, .shift = 0, .size = 4 },
978 .reg_div = { .reg = S5P_CLKDIV_LCD0, .shift = 0, .size = 4 },
983 .enable = exynos4_clksrc_mask_lcd1_ctrl,
986 .sources = &clkset_group,
987 .reg_src = { .reg = S5P_CLKSRC_LCD1, .shift = 0, .size = 4 },
988 .reg_div = { .reg = S5P_CLKDIV_LCD1, .shift = 0, .size = 4 },
993 .enable = exynos4_clksrc_mask_fsys_ctrl,
994 .ctrlbit = (1 << 24),
996 .sources = &clkset_mout_corebus,
997 .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 24, .size = 1 },
998 .reg_div = { .reg = S5P_CLKDIV_FSYS0, .shift = 20, .size = 4 },
1003 .enable = exynos4_clksrc_mask_peril1_ctrl,
1004 .ctrlbit = (1 << 16),
1006 .sources = &clkset_group,
1007 .reg_src = { .reg = S5P_CLKSRC_PERIL1, .shift = 16, .size = 4 },
1008 .reg_div = { .reg = S5P_CLKDIV_PERIL1, .shift = 0, .size = 4 },
1013 .enable = exynos4_clksrc_mask_peril1_ctrl,
1014 .ctrlbit = (1 << 20),
1016 .sources = &clkset_group,
1017 .reg_src = { .reg = S5P_CLKSRC_PERIL1, .shift = 20, .size = 4 },
1018 .reg_div = { .reg = S5P_CLKDIV_PERIL1, .shift = 16, .size = 4 },
1023 .enable = exynos4_clksrc_mask_peril1_ctrl,
1024 .ctrlbit = (1 << 24),
1026 .sources = &clkset_group,
1027 .reg_src = { .reg = S5P_CLKSRC_PERIL1, .shift = 24, .size = 4 },
1028 .reg_div = { .reg = S5P_CLKDIV_PERIL2, .shift = 0, .size = 4 },
1031 .name = "sclk_fimg2d",
1034 .sources = &clkset_mout_g2d,
1035 .reg_src = { .reg = S5P_CLKSRC_IMAGE, .shift = 8, .size = 1 },
1036 .reg_div = { .reg = S5P_CLKDIV_IMAGE, .shift = 0, .size = 4 },
1041 .parent = &clk_dout_mmc0.clk,
1042 .enable = exynos4_clksrc_mask_fsys_ctrl,
1043 .ctrlbit = (1 << 0),
1045 .reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 8, .size = 8 },
1050 .parent = &clk_dout_mmc1.clk,
1051 .enable = exynos4_clksrc_mask_fsys_ctrl,
1052 .ctrlbit = (1 << 4),
1054 .reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 24, .size = 8 },
1059 .parent = &clk_dout_mmc2.clk,
1060 .enable = exynos4_clksrc_mask_fsys_ctrl,
1061 .ctrlbit = (1 << 8),
1063 .reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 8, .size = 8 },
1068 .parent = &clk_dout_mmc3.clk,
1069 .enable = exynos4_clksrc_mask_fsys_ctrl,
1070 .ctrlbit = (1 << 12),
1072 .reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 24, .size = 8 },
1077 .parent = &clk_dout_mmc4.clk,
1078 .enable = exynos4_clksrc_mask_fsys_ctrl,
1079 .ctrlbit = (1 << 16),
1081 .reg_div = { .reg = S5P_CLKDIV_FSYS3, .shift = 8, .size = 8 },
1085 /* Clock initialization code */
1086 static struct clksrc_clk *sysclks[] = {
1117 static int xtal_rate;
1119 static unsigned long exynos4_fout_apll_get_rate(struct clk *clk)
1121 return s5p_get_pll45xx(xtal_rate, __raw_readl(S5P_APLL_CON0), pll_4508);
1124 static struct clk_ops exynos4_fout_apll_ops = {
1125 .get_rate = exynos4_fout_apll_get_rate,
1128 void __init_or_cpufreq exynos4_setup_clocks(void)
1130 struct clk *xtal_clk;
1135 unsigned long vpllsrc;
1137 unsigned long armclk;
1138 unsigned long sclk_dmc;
1139 unsigned long aclk_200;
1140 unsigned long aclk_100;
1141 unsigned long aclk_160;
1142 unsigned long aclk_133;
1145 printk(KERN_DEBUG "%s: registering clocks\n", __func__);
1147 xtal_clk = clk_get(NULL, "xtal");
1148 BUG_ON(IS_ERR(xtal_clk));
1150 xtal = clk_get_rate(xtal_clk);
1156 printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal);
1158 apll = s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON0), pll_4508);
1159 mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P_MPLL_CON0), pll_4508);
1160 epll = s5p_get_pll46xx(xtal, __raw_readl(S5P_EPLL_CON0),
1161 __raw_readl(S5P_EPLL_CON1), pll_4600);
1163 vpllsrc = clk_get_rate(&clk_vpllsrc.clk);
1164 vpll = s5p_get_pll46xx(vpllsrc, __raw_readl(S5P_VPLL_CON0),
1165 __raw_readl(S5P_VPLL_CON1), pll_4650);
1167 clk_fout_apll.ops = &exynos4_fout_apll_ops;
1168 clk_fout_mpll.rate = mpll;
1169 clk_fout_epll.rate = epll;
1170 clk_fout_vpll.rate = vpll;
1172 printk(KERN_INFO "EXYNOS4: PLL settings, A=%ld, M=%ld, E=%ld V=%ld",
1173 apll, mpll, epll, vpll);
1175 armclk = clk_get_rate(&clk_armclk.clk);
1176 sclk_dmc = clk_get_rate(&clk_sclk_dmc.clk);
1178 aclk_200 = clk_get_rate(&clk_aclk_200.clk);
1179 aclk_100 = clk_get_rate(&clk_aclk_100.clk);
1180 aclk_160 = clk_get_rate(&clk_aclk_160.clk);
1181 aclk_133 = clk_get_rate(&clk_aclk_133.clk);
1183 printk(KERN_INFO "EXYNOS4: ARMCLK=%ld, DMC=%ld, ACLK200=%ld\n"
1184 "ACLK100=%ld, ACLK160=%ld, ACLK133=%ld\n",
1185 armclk, sclk_dmc, aclk_200,
1186 aclk_100, aclk_160, aclk_133);
1188 clk_f.rate = armclk;
1189 clk_h.rate = sclk_dmc;
1190 clk_p.rate = aclk_100;
1192 for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
1193 s3c_set_clksrc(&clksrcs[ptr], true);
1196 static struct clk *clks[] __initdata = {
1197 /* Nothing here yet */
1200 void __init exynos4_register_clocks(void)
1204 s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
1206 for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++)
1207 s3c_register_clksrc(sysclks[ptr], 1);
1209 s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
1210 s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
1212 s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
1213 s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));